-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Adding GetCodeHeaderData cDAC API #119609
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
Conversation
rcj1
commented
Sep 12, 2025
- Adding GetCodeHeaderData cDAC API
- Implementing unwind data size on platforms other than x86 in helper class
- required additions to hot/cold lookup helpers
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.
Pull Request Overview
This PR adds the GetCodeHeaderData
cDAC API implementation, which retrieves code header information for a given instruction pointer. The implementation includes hot/cold region detection and unwind data size calculations across different architectures.
- Replaces the legacy interface implementation with a proper cDAC contract-based implementation
- Adds support for calculating unwind data sizes on all supported architectures (X64, ARM, ARM64, LoongArch64, RiscV64)
- Implements hot/cold method region detection and size calculation through execution manager extensions
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
SOSDacImpl.cs | Implements GetCodeHeaderData with proper error handling and debug validation |
ISOSDacInterface.cs | Adds strongly-typed DacpCodeHeaderData struct and JITTypes enum |
UnwindInfo.cs | Extends UnwindInfo data class to support unwind codes on non-x86 platforms |
UnwindDataSize.cs | New helper class for calculating unwind data sizes across all architectures |
HotColdLookup.cs | Adds method to retrieve hot/cold region boundaries |
ExecutionManager files | Adds new APIs for method region info, JIT type detection, and non-virtual entry lookup |
datadescriptor.inc | Updates UnwindInfo and adds UnwindCode type definitions |
ExecutionManager.md | Documents the new ExecutionManager APIs and their implementation details |
...ractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.ReadyToRunJitManager.cs
Show resolved
Hide resolved
Tagging subscribers to this area: @steveisok, @dotnet/dotnet-diag |
Separate PR idea: more detailed hot/cold map documentation? @elinor-fung |
if (/* no corresponding range section */) | ||
return null; | ||
|
||
if (/* range flags indicate RangeList */) |
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.
@elinor-fung @jkotas any way to simplify this, can these checks be absorbed into GetMethodDescFromStubAddress?
In any case I think we need the capability to turn this additional search on and off because SOS uses the failure case of GetMethodDescPtrFromIP to indicate some things about the type of method we are looking at. Here is an (undocumented) example but there are more:
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.
I think we need to have two different non-legacy methods:
-
API that takes IP that points to the start or into middle of an actual method code, and maps it MethodDesc, hot/cold region sizes, GCInfo, etc.
GetMethodRegionInfo
looks close. -
API that take method entrypoint (that may not actually be a pointer to the actual code in some configuration - see my other comment), and maps it to MethodDesc. Equivalent of runtime's NonVirtualEntry2MethodDesc.
The legacy methods can be hopefully implemented using these two APIs in a compatible-enough way.
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.
It looks like our method for computing method size (summing RUNTIME_FUNCTION
s lengths) is different than the runtimes (reading the GCInfo). Will this always yield the same result?
private enum JITTypes | ||
{ | ||
TYPE_UNKNOWN = 0, | ||
TYPE_JIT = 1, | ||
TYPE_PJIT = 2, | ||
TYPE_INTERPRETER = 3 | ||
}; |
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.
We can make this public in IExecutionManager
and change the return type of GetJitType
to JitType
.
....Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs
Outdated
Show resolved
Hide resolved
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/UnwindInfo.cs
Outdated
Show resolved
Hide resolved
...iagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/Helpers/UnwindDataSize.cs
Outdated
Show resolved
Hide resolved
...iagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/Helpers/UnwindDataSize.cs
Outdated
Show resolved
Hide resolved
...iagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/Helpers/UnwindDataSize.cs
Outdated
Show resolved
Hide resolved
if (codeBlockHandle == null) | ||
{ | ||
TargetPointer methodDesc = executionManager.NonVirtualEntry2MethodDesc(targetCodePointer); | ||
if (methodDesc == TargetPointer.Null) | ||
throw new ArgumentException(); | ||
data->MethodDescPtr = methodDesc.ToClrDataAddress(_target); | ||
data->JITType = JITTypes.TYPE_UNKNOWN; | ||
data->GCInfo = 0; | ||
data->MethodStart = 0; | ||
data->MethodSize = 0; | ||
data->ColdRegionStart = 0; | ||
} |
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.
Is there a reason that we don't set HotRegionSize
or ColdRegionSize
here? I see that the DAC doesn't, but that was probably an oversight and could get updated for consistency.
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.
It is how this API communicates that the address is a stub (most likely a precode these days) and not an actual code.
HotRegionSize/ColdRegionSize may not be even readily available for some of the stubs.
...ed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IExecutionManager.cs
Show resolved
Hide resolved
I do not think these will yield the same result. There can be padding or data that's not included in the unwind infos in between the unwind infos or at the end. |
Yes I now notice the results being different in CI with the cDAC giving significantly higher method lengths. |
Waiting for GetStackReferences to merge (this should include GCInfo decoding stuff) |
Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it. |