[cDAC] Implement DacDbi GetStackWalkCurrentFrameInfo#130646
Conversation
Co-authored-by: rcj1 <77995559+rcj1@users.noreply.github.com>
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
There was a problem hiding this comment.
Pull request overview
This PR extends the cDAC stack-walking and runtime type system contracts to support richer per-frame debugger data (frame classification, funclet/interrupt state, ambient SP, exact generic args token) and wires that through the legacy DacDbi implementation for GetStackWalkCurrentFrameInfo.
Changes:
- Implements
DacDbiImpl.GetStackWalkCurrentFrameInfousing new StackWalk/GCInfo contract APIs and expands frame classification logic (managed EH helpers, runtime entry point, native runtime-unwindable markers). - Extends cDAC contracts/abstractions: async method flags API, varargs detection, well-known MethodTables/MethodDescs,
StackWalkFrameInfo, and GCInfo helpers (ambient SP + generic instantiation context slot). - Updates unit tests and contract docs to reflect the new async flags behavior and new StackWalk/RuntimeTypeSystem/GCInfo surface.
Show a summary per file
| File | Description |
|---|---|
| src/native/managed/cdac/tests/UnitTests/MethodDescTests.cs | Updates async-thunk classification test coverage to validate the new GetAsyncMethodFlags semantics (variant/return-dropping flags). |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs | Adds missing legacy enums/constants needed by the new frame-info shaping (FrameType, MAX_ILNUM, mapping result). |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs | Implements GetStackWalkCurrentFrameInfo and integrates new async flag checks + vararg + exact generic args token + ambient SP plumbing. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.ExceptionHandling.cs | Adds secondary-walk logic to locate funclet parent method frame info. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs | Extends stackwalk handle state (interrupt/fault), and implements GetCurrentFrameInfo + GetExactGenericArgsToken and helpers. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs | Adds well-known MT/MD globals accessors, exposes raw async flags, and implements IsVarArg. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/IGCInfoDecoder.cs | Extends decoder interface with generic-inst-context slot discovery + ambient SP query. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/X86/GCInfo.cs | Implements ambient SP computation for x86 GC info and reports no generic-inst-context slot for the x86 format. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfoX86_1.cs | Plumbs new ambient SP / generic-inst-context APIs through the x86 GCInfo contract. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfoDecoder.cs | Implements generic-inst-context stack-slot discovery for the non-x86 decoder; ambient SP returns null for non-x86. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfo_1.cs | Plumbs new APIs through the general GCInfo contract surface. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs | Adds new global names for the additional well-known MT/MD pointers. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStackWalk.cs | Adds StackWalkFrameInfo and new StackWalk APIs needed by DacDbi frame info shaping. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IRuntimeTypeSystem.cs | Adds async flag enum/API, new well-known method desc API, and IsVarArg. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IGCInfo.cs | Adds ambient SP and generic-inst-context slot APIs. |
| src/coreclr/vm/datadescriptor/datadescriptor.inc | Exposes additional well-known MT/MD globals to cDAC. |
| src/coreclr/inc/gcinfotypes.h | Annotates INVALID_SYNC_OFFSET as a cDAC contract dependency. |
| src/coreclr/inc/eetwain.h | Annotates SHADOW_SP_BITS as a cDAC contract dependency. |
| docs/design/datacontracts/StackWalk.md | Documents new StackWalk APIs and frame-info semantics. |
| docs/design/datacontracts/RuntimeTypeSystem.md | Documents new well-known MT/MD and async-flag/vararg APIs. |
| docs/design/datacontracts/GCInfo.md | Documents new GCInfo APIs and the constants they depend on. |
Copilot's findings
Comments suppressed due to low confidence (3)
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs:1698
GetStackWalkCurrentFrameInfoonly writes*pRetValat the end of thetryblock. If any exception is thrown before that point, the out-pointer remains uninitialized, which can lead to reading undefined data on the caller side even though an HRESULT failure is returned.
hr = HResults.S_FALSE;
}
}
catch (System.Exception ex)
{
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs:5738
- Avoid
Enum.HasFlaghere to prevent boxing on a potentially hot path (async locals enumeration).
Contracts.ModuleHandle handle = loader.GetModuleHandleFromModulePtr(new TargetPointer(pModule));
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs:1833
ClassifyManagedFramecallsGetWellKnownMethodTable/GetWellKnownMethodDescrepeatedly. Each call can trigger target reads; caching these values once per classification reduces repeated reads and also avoids accidentally matchingTargetPointer.Nullif any well-known global isn't initialized.
catch (System.Exception ex)
{
hr = ex.HResult;
}
#if DEBUG
if (_legacy is not null)
- Files reviewed: 21/21 changed files
- Comments generated: 4
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| @@ -92,7 +102,7 @@ public interface IStackWalk : IContract | |||
| IEnumerable<IStackDataFrameHandle> CreateStackWalk(ThreadData threadData) => throw new NotImplementedException(); | |||
| IEnumerable<IStackDataFrameHandle> CreateStackWalk(ThreadData threadData, byte[] contextBuffer, bool isFirst = true) => throw new NotImplementedException(); | |||
| IReadOnlyList<StackReferenceData> WalkStackReferences(ThreadData threadData, bool resolveInteriorPointers) => throw new NotImplementedException(); | |||
| byte[] GetRawContext(IStackDataFrameHandle stackDataFrameHandle, StackwalkFlag flags = StackwalkFlag.Default) => throw new NotImplementedException(); | |||
| byte[] GetRawContext(IStackDataFrameHandle stackDataFrameHandle) => throw new NotImplementedException(); | |||
| TargetPointer GetFrameAddress(IStackDataFrameHandle stackDataFrameHandle) => throw new NotImplementedException(); | |||
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
and supporting APIs on GC info contract
Implement GetStackWalkCurrentFrameInfo DacDbi API