dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.93k stars 4.64k forks source link

[MSVC][x86] Failed to build with error C2488: 'naked' can only be applied to non-member function definitions #104460

Open NEIL-smtg opened 2 months ago

NEIL-smtg commented 2 months ago

Description

Note: To reproduce this, you'll need wait for VS 2022 17.12 Preview or later version to ship which will contain this change.

Recently, we have been building this project using the latest build of MSVC, and we have encountered the following error:

runtime\src\coreclr\debug\ee\debugger.cpp(13904) :
error C2488: 'Debugger::GenericHijackFunc': 'naked' can only be applied to non-member function definitions

Complete build log: Build.log

Reproduction Steps

  1. Open X86 Native Tools Command Prompt for VS 2022
  2. git clone https://github.com/dotnet/runtime.git
  3. cd runtime
  4. set CL=/wd5281
  5. .\build.cmd -subset clr+libs -c release -arch x86 2>&1

Expected behavior

It compiles.

Actual behavior

runtime\src\coreclr\debug\ee\debugger.cpp(13904) :
error C2488: 'Debugger::GenericHijackFunc': 'naked' can only be applied to non-member function definitions

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

This is the narrowed down repro, test.cpp:

struct Foo {
    __declspec(naked) void func1() {} // gets C2488
    void func2();
    __declspec(naked) static void func3() {} // gets C2488
};

#if defined(TARGET_X86)
__declspec(naked)
#endif
void Foo::func2() {} // should also get C2488

repro command:

cl /c test.cpp /DTARGET_X86

For current version, you will only ger error C2488 on line 2 and 4. For the upcoming version of VS, the last line will be also getting the error C2488.

dotnet-policy-service[bot] commented 2 months ago

Tagging subscribers to this area: @hoyosjs See info in area-owners.md if you want to be subscribed.

huoyaoyuan commented 2 months ago

This was touched in #102834, but it was already naked then.

Does it make sense to port the naked function to asm now?

jkotas commented 2 months ago

Does it make sense to port the naked function to asm now?

Yes. Inline assembler has always been a factory for problems. We try to avoid inline asm for any new code.

huoyaoyuan commented 2 months ago

Well I want to understand more about this specific function:

https://github.com/dotnet/runtime/blob/a7efcd9ca9255dc9faa8b4a2761cdfdb62619610/src/coreclr/debug/ee/debugger.cpp#L13918-L13960

It just pushes and pops ebp frame around the call to GenericHijackFuncHelper. What's the requirement around this?

When written as ordinal function, it compiles to the same code of win-x64:

call GenericHijackFuncHelper
jmp ExceptionNotForRuntime

On win-arm64, the return-address saving is around the two function calls:

str lr,[sp,#-0x10]!
bl GenericHijackFuncHelper
bl ExceptionNotForRuntime
ldr lr,[sp],#0x10
ret
jkotas commented 2 months ago

https://github.com/dotnet/runtime/blob/a7efcd9ca9255dc9faa8b4a2761cdfdb62619610/src/coreclr/debug/di/rsthread.cpp#L3879-L3881 comment talks about this