-
Notifications
You must be signed in to change notification settings - Fork 5.4k
[cDAC] implement GetRuntimeNameByAddress #127134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
610be95
1b691c2
f01a100
7122161
d999faf
06b4f83
fa28222
634d396
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5309,86 +5309,6 @@ ClrDataAccess::GetJitHelperName(IN TADDR address) | |||||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // This function expects more memory than maybe needed. | ||||||||||||||||||||||||||||||
| static int FormatCLRStubName( | ||||||||||||||||||||||||||||||
| _In_opt_z_ LPCWSTR stubNameMaybe, | ||||||||||||||||||||||||||||||
| _In_ TADDR stubAddr, | ||||||||||||||||||||||||||||||
| _In_ ULONG32 bufLen, | ||||||||||||||||||||||||||||||
| _Out_ ULONG32 *symbolLen, | ||||||||||||||||||||||||||||||
| _Out_writes_bytes_opt_(bufLen) WCHAR* symbolBuf) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| // Parts needed to construct a name: | ||||||||||||||||||||||||||||||
| // With stub manager name: "CLRStub[%s]@%p" | ||||||||||||||||||||||||||||||
| // No stub manager name: "CLRStub@%p" | ||||||||||||||||||||||||||||||
| const WCHAR formatName_Prefix[] = W("CLRStub"); | ||||||||||||||||||||||||||||||
| const WCHAR formatName_OpenBracket[] = W("["); | ||||||||||||||||||||||||||||||
| const WCHAR formatName_CloseBracket[] = W("]"); | ||||||||||||||||||||||||||||||
| const WCHAR formatName_PrefixEnd[] = W("@"); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Compute the address as a string safely. | ||||||||||||||||||||||||||||||
| WCHAR addrString[Max64BitHexString + 1]; | ||||||||||||||||||||||||||||||
| FormatInteger(addrString, ARRAY_SIZE(addrString), "%p", stubAddr); | ||||||||||||||||||||||||||||||
| size_t addStringLen = u16_strlen(addrString); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Compute maximum length, include the null terminator. | ||||||||||||||||||||||||||||||
| size_t formatName_MaxLen = ARRAY_SIZE(formatName_Prefix) // Include trailing null | ||||||||||||||||||||||||||||||
| + ARRAY_SIZE(formatName_PrefixEnd) - 1 | ||||||||||||||||||||||||||||||
| + addStringLen; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Consider stub manager name | ||||||||||||||||||||||||||||||
| size_t stubManagedNameLen = 0; | ||||||||||||||||||||||||||||||
| if (stubNameMaybe != NULL) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| stubManagedNameLen = u16_strlen(stubNameMaybe); | ||||||||||||||||||||||||||||||
| formatName_MaxLen += ARRAY_SIZE(formatName_OpenBracket) - 1; | ||||||||||||||||||||||||||||||
| formatName_MaxLen += ARRAY_SIZE(formatName_CloseBracket) - 1; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| HRESULT hr = S_FALSE; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Compute the exact length needed. | ||||||||||||||||||||||||||||||
| const size_t lenNeeded = formatName_MaxLen + stubManagedNameLen; | ||||||||||||||||||||||||||||||
| if (lenNeeded <= bufLen) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| size_t written = 0; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Set the prefix | ||||||||||||||||||||||||||||||
| wcscpy_s(symbolBuf, bufLen - written, formatName_Prefix); | ||||||||||||||||||||||||||||||
| written += ARRAY_SIZE(formatName_Prefix) - 1; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Add the name | ||||||||||||||||||||||||||||||
| if (stubManagedNameLen > 0) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| wcscat_s(symbolBuf, bufLen - written, formatName_OpenBracket); | ||||||||||||||||||||||||||||||
| written += ARRAY_SIZE(formatName_OpenBracket) - 1; | ||||||||||||||||||||||||||||||
| wcscat_s(symbolBuf, bufLen - written, stubNameMaybe); | ||||||||||||||||||||||||||||||
| written += stubManagedNameLen; | ||||||||||||||||||||||||||||||
| wcscat_s(symbolBuf, bufLen - written, formatName_CloseBracket); | ||||||||||||||||||||||||||||||
| written += ARRAY_SIZE(formatName_CloseBracket) - 1; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Append the prefix end | ||||||||||||||||||||||||||||||
| wcscat_s(symbolBuf, bufLen - written, formatName_PrefixEnd); | ||||||||||||||||||||||||||||||
| written += ARRAY_SIZE(formatName_PrefixEnd) - 1; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Append the address | ||||||||||||||||||||||||||||||
| wcscat_s(symbolBuf, bufLen - written, addrString); | ||||||||||||||||||||||||||||||
| written += addStringLen; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| hr = S_OK; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (symbolLen) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| if (!FitsIn<ULONG32>(lenNeeded)) | ||||||||||||||||||||||||||||||
| return COR_E_OVERFLOW; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| *symbolLen = (ULONG32)lenNeeded; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| return hr; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| HRESULT | ||||||||||||||||||||||||||||||
| ClrDataAccess::RawGetMethodName( | ||||||||||||||||||||||||||||||
| /* [in] */ CLRDATA_ADDRESS address, | ||||||||||||||||||||||||||||||
|
|
@@ -5422,120 +5342,41 @@ ClrDataAccess::RawGetMethodName( | |||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| PTR_StubManager pStubManager; | ||||||||||||||||||||||||||||||
| MethodDesc* methodDesc = NULL; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| EECodeInfo codeInfo(GetInterpreterCodeFromInterpreterPrecodeIfPresent(TO_TADDR(address))); | ||||||||||||||||||||||||||||||
| if (codeInfo.IsValid()) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| if (displacement) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| *displacement = codeInfo.GetRelOffset(); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| methodDesc = codeInfo.GetMethodDesc(); | ||||||||||||||||||||||||||||||
| goto NameFromMethodDesc; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| pStubManager = StubManager::FindStubManager(TO_TADDR(address)); | ||||||||||||||||||||||||||||||
| if (pStubManager != NULL) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| if (displacement) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| *displacement = 0; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||
| // Special-cased stub managers | ||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||
| if (pStubManager == PrecodeStubManager::g_pManager) | ||||||||||||||||||||||||||||||
| LPCWSTR wszStubManagerName = pStubManager->GetStubManagerName(TO_TADDR(address)); | ||||||||||||||||||||||||||||||
| _ASSERTE(wszStubManagerName != NULL); | ||||||||||||||||||||||||||||||
| if (u16_strcmp(wszStubManagerName, W("ThePreStub")) != 0 && u16_strcmp(wszStubManagerName, W("InteropDispatchStub")) != 0 && u16_strcmp(wszStubManagerName, W("TailCallStub")) != 0) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| PCODE alignedAddress = AlignDown(TO_TADDR(address), PRECODE_ALIGNMENT); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #ifdef TARGET_ARM | ||||||||||||||||||||||||||||||
| alignedAddress += THUMB_CODE; | ||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| SIZE_T maxPrecodeSize = sizeof(StubPrecode); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #ifdef HAS_THISPTR_RETBUF_PRECODE | ||||||||||||||||||||||||||||||
| maxPrecodeSize = max((size_t)maxPrecodeSize, sizeof(ThisPtrRetBufPrecode)); | ||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| for (SIZE_T i = 0; i < maxPrecodeSize / PRECODE_ALIGNMENT; i++) | ||||||||||||||||||||||||||||||
| // Skip the stubs that are just assembly helpers. | ||||||||||||||||||||||||||||||
| wcscpy_s(symbolBuf, bufLen, wszStubManagerName); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
| wcscpy_s(symbolBuf, bufLen, wszStubManagerName); | |
| ULONG32 stubManagerNameLen = static_cast<ULONG32>(wcslen(wszStubManagerName) + 1); | |
| if (symbolLen != NULL) | |
| { | |
| *symbolLen = stubManagerNameLen; | |
| } | |
| if (symbolBuf != NULL) | |
| { | |
| if (wcscpy_s(symbolBuf, bufLen, wszStubManagerName) != 0) | |
| { | |
| return S_FALSE; | |
| } | |
| } |
Copilot
AI
Apr 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stub-manager path copies wszStubManagerName into symbolBuf unconditionally and returns S_OK, but it doesn't (1) handle the common "size query" pattern where symbolBuf is null / bufLen is 0, (2) set *symbolLen, or (3) return S_FALSE when the buffer is too small. This can lead to null dereferences, missing length output, and incorrect HRESULTs. Please follow the same output contract as GetFullMethodName/ConvertUtf8: compute required length, set symbolLen when non-null, write only when symbolBuf is non-null and bufLen is sufficient (or truncate + S_FALSE as appropriate).
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -113,8 +113,6 @@ enum StubCodeBlockKind : int | |
| // Last valid value. Note that the definition is duplicated in debug\daccess\fntableaccess.cpp | ||
| STUB_CODE_BLOCK_LAST = 0xF, | ||
| // Placeholders returned by code:GetStubCodeBlockKind | ||
| STUB_CODE_BLOCK_NOCODE = 0x10, | ||
| STUB_CODE_BLOCK_MANAGED = 0x11, | ||
| STUB_CODE_BLOCK_STUBLINK = 0x12, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this actually used anywhere? I see it used in a few case statements, but not actually passed in anywhere. |
||
| // Placeholder used by ReadyToRun images | ||
| STUB_CODE_BLOCK_METHOD_CALL_THUNK = 0x13, | ||
|
|
@@ -128,8 +126,6 @@ inline const char *GetStubCodeBlockKindString(StubCodeBlockKind kind) | |
| return "JumpStub"; | ||
| case STUB_CODE_BLOCK_STUBLINK: | ||
| return "StubLinkStub"; | ||
| case STUB_CODE_BLOCK_MANAGED: | ||
| return "Managed"; | ||
| case STUB_CODE_BLOCK_METHOD_CALL_THUNK: | ||
| return "MethodCallThunk"; | ||
| #ifdef FEATURE_TIERED_COMPILATION | ||
|
|
@@ -793,6 +789,7 @@ template<> struct cdac_data<RangeSection> | |
| static constexpr size_t Flags = offsetof(RangeSection, _flags); | ||
| static constexpr size_t HeapList = offsetof(RangeSection, _pHeapList); | ||
| static constexpr size_t R2RModule = offsetof(RangeSection, _pR2RModule); | ||
| static constexpr size_t RangeList = offsetof(RangeSection, _pRangeList); | ||
| }; | ||
|
|
||
| enum class RangeSectionLockState | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "Skip the stubs that are just assembly helpers." doesn't match the logic: the code returns the stub manager name when it is not one of the listed assembly-helper names. Please update the comment to reflect the actual behavior (or invert the condition if the comment is what was intended).