Skip to content

[DAC] ISOSDacInterface:GetMethodDescData reads from nullptr #109877

@max-charlamb

Description

@max-charlamb

Description

GetMethodDescData's ReJIT features are wrapped in a try/catch to safely disregard ReJIT information if it can't be fetched.

In some circumstances attempting to fetch ReJIT data will read a nullptr causing an AV error which is caught on Windows, but not on Linux or MacOS.

This occurs when GetMethodDescData is called on a function which has a pending ReJIT request but before the new native code is generated.

Reproduction Steps

  1. Build the standalone version of the coreclr test src/tests/profiler/rejit/rejit.cs. For building instructions see coreclr testing.
  2. Run the test with a debugger attached.
  3. Add a breakpoint on line 25 of rejit.cs.
  4. Invoke GetMethodDescData on InlineeTarget (the function where ReJIT is being applied) when paused at the breakpoint. The easiest way I have found to do so is using SOS and calling !dumpmd or !ip2md on the function.

Expected behavior

The ReJIT try/catch should safely fail when ReJIT information cannot be fetched on all platforms.

Actual behavior

On line 1051 of request.cpp, we try to fetch the activeNativeCodeVersion, however since there is not yet native code for the newly generated IL version, activeNativeCodeVersion is effectively null with a nullptr for its PTR_MethodDesc. Then when we try to copy the activeNativeCodeVersion to the output ReJIT data, we read GetMemberDef off of this nullptr causing an AV error.

>	mscordaccore.dll!MethodDesc::GetMethodDescChunkIndex() Line 2363	C++
 	mscordaccore.dll!MethodDesc::GetMethodDescChunk() Line 2370	C++
 	mscordaccore.dll!MethodDesc::GetMemberDef() Line 3487	C++
 	mscordaccore.dll!NativeCodeVersion::GetILCodeVersion() Line 247	C++
 	mscordaccore.dll!CopyNativeCodeVersionToReJitData(NativeCodeVersion nativeCodeVersion, NativeCodeVersion activeCodeVersion, DacpReJitData * pReJitData) Line 908	C++
 	mscordaccore.dll!ClrDataAccess::GetMethodDescData(unsigned __int64 methodDesc, unsigned __int64 ip, DacpMethodDescData * methodDescData, unsigned long cRevertedRejitVersions, DacpReJitData * rgRevertedRejitData, unsigned long * pcNeededRevertedRejitData) Line 1053	C++
 	cdacreader.dll!cdacreader__Microsoft_Diagnostics_DataContractReader_Legacy_ISOSDacInterface_F837734AB7F467318D6BB65895B8BE78FD74B596B7C3ABB7EC0274CEE4E792788__InterfaceImplementation__global__Microsoft_Diagnostics_DataContractReader_Legacy_ISOSDacInterface_GetMethodDescData() Line 283	Unknown
 	cdacreader.dll!cdacreader_Microsoft_Diagnostics_DataContractReader_Legacy_SOSDacImpl__Microsoft_Diagnostics_DataContractReader_Legacy_ISOSDacInterface_GetMethodDescData() Line 318	Unknown
 	cdacreader.dll!cdacreader__Microsoft_Diagnostics_DataContractReader_Legacy_ISOSDacInterface_F837734AB7F467318D6BB65895B8BE78FD74B596B7C3ABB7EC0274CEE4E792788__InterfaceImplementation__ABI_GetMethodDescData() Line 1642	Unknown
 	[Inline Frame] sos.dll!DacpMethodDescData::Request(ISOSDacInterface * sos, unsigned __int64) Line 578	C++
 	sos.dll!DumpMT(IDebugClient * client, const char * args) Line 1272	C++
 	dbgeng.dll!ExtensionInfo::CallA(DebugClient * Client, const wchar_t * Func, const char * FuncA, const char * ArgsA, HRESULT * ExtStatus) Line 5143	C++
 	dbgeng.dll!ExtensionInfo::Call(DebugClient * Client, wchar_t * Func, const wchar_t * Args, HRESULT * ExtStatus) Line 5212	C++
 	dbgeng.dll!ExtensionInfo::CallAny(DebugClient * Client, ExtensionInfo * Ext, wchar_t * Function, const wchar_t * Arguments, int ModuleSpecified, int ShowWarnings, const wchar_t * LoadReason, HRESULT * ExtStatus) Line 5307	C++
 	dbgeng.dll!ParseBangCmd(DebugClient * Client, int BuiltInOnly) Line 3696	C++
 	dbgeng.dll!ProcessCommands(DebugClient * Client, int Nested) Line 3346	C++
 	dbgeng.dll!ProcessCommandsAndCatch(DebugClient * Client, int Nested, CMD_CATCH CatchWhich) Line 3481	C++
 	dbgeng.dll!Execute(DebugClient * Client, const wchar_t * Command, unsigned long Flags, CMD_CATCH CatchWhich) Line 3408	C++
 	dbgeng.dll!DebugClient::ExecuteWide(unsigned long OutputControl, const wchar_t * Command, unsigned long Flags) Line 3539	C++
 	dbgeng.dll!SFN_IDebugControlN_ExecuteWide(IUnknown * __drpc_If, DbgRpcConnection * __drpc_Conn, DbgRpcCall * __drpc_Call, unsigned char * __drpc_InData, unsigned char * __drpc_OutData) Line 8689	C++
 	dbgeng.dll!DbgRpcReceiveCalls(DbgRpcConnection * Conn, DbgRpcCall * Call, unsigned char * * InOutData) Line 338	C++
 	dbgeng.dll!DbgRpcClientThread(void * ThreadParam) Line 1770	C++
 	kernel32.dll!BaseThreadInitThunk(unsigned long RunProcessInit, long(*)(void *) StartAddress, void * Argument) Line 77	C
 	ntdll.dll!RtlUserThreadStart(long(*)(void *) StartAddress, void * Argument) Line 1184	C

Image

Regression?

No response

Known Workarounds

No response

Configuration

  • Using private build of the repo
  • Windows 11
  • x64

Other information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions