[cDAC] Stackwalk DacDbi APIs#129091
Draft
rcj1 wants to merge 8 commits into
Draft
Conversation
Contributor
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR expands the cDAC StackWalk and Debugger contracts to support runtime hijack-stub detection and hijacked-context recovery, updates context retrieval to use caller-provided aligned buffers with HRESULT-based error reporting, and wires up corresponding DacDbi stack-walk APIs with updated tests and documentation.
Changes:
- Add Debugger contract support for hijack stub range table (
RgHijackFunction+MemoryRange) and implementIDebugger.IsRuntimeUnwindableStub. - Extend StackWalk contract with hijack-context recovery and seed-context stack-walk support; change
GetContextto fill a caller-provided, 16-byte-aligned buffer and return HRESULTs. - Implement DacDbi stack-walk methods (create/delete/set/get/unwind/check) on top of the cDAC contracts, with test and dump-test updates for alignment and signature changes.
Show a summary per file
| File | Description |
|---|---|
| src/native/managed/cdac/tests/UnitTests/DebuggerTests.cs | Adds unit tests and mock-target plumbing for hijack-stub detection via RgHijackFunction/MemoryRange. |
| src/native/managed/cdac/tests/UnitTests/DacDbiImplTests.cs | Updates tests to match CheckContext signature change (byte* instead of nint). |
| src/native/managed/cdac/tests/TestInfrastructure/TestPlaceholderTarget.cs | Updates TryGetThreadContext override to return HRESULT (int). |
| src/native/managed/cdac/tests/DumpTests/StackWalkDumpTests.cs | Updates dump test to use aligned native memory and validate HRESULT-based GetContext. |
| src/native/managed/cdac/tests/DumpTests/DacDbi/DacDbiStackWalkDumpTests.cs | Updates dump tests to use aligned buffers when calling contract GetContext. |
| src/native/managed/cdac/tests/DataGenerator/TestTarget.cs | Updates TryGetThreadContext override to return HRESULT (int). |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs | Changes TryGetThreadContext to return HRESULT from the underlying data-target delegate. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs | Updates COM surface signatures for stack-walk context pointers (byte*) and adds CorDebugSetContextFlags. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/Helpers/StackWalkHandleData.cs | Introduces managed handle state for cDAC-backed DacDbi stack walking. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs | Implements DacDbi stack-walk APIs using cDAC StackWalk + Debugger contracts, with optional legacy mirroring/debug validation. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Microsoft.Diagnostics.DataContractReader.Contracts.csproj | Adds System.HResults to enable HRESULT constants in contracts. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/DataType.cs | Adds DataType.MemoryRange for hijack table entries. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MemoryRange.cs | Adds cDAC MemoryRange data descriptor type (start + size). |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Debugger.cs | Adds RgHijackFunction field for hijack function range table pointer. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalk_1.cs | Adds seed-context CreateStackWalk, hijacked-context recovery, HRESULT-buffer GetContext, and aligned scratch usage for OS context retrieval. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/IPlatformAgnosticContext.cs | Adds ContextAlignment constant (16) for CONTEXT buffer alignment requirements. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Debugger_1.cs | Implements IDebugger.IsRuntimeUnwindableStub using hijack range table scanning. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs | Adds MaxHijackFunctions global name used by Debugger hijack-table scanning. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs | Changes TryGetThreadContext to return HRESULT instead of bool (API contract shift). |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStackWalk.cs | Adds seed-context CreateStackWalk overload and changes GetContext to HRESULT + caller buffer; adds RetrieveHijackedContext. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDebugger.cs | Adds IsRuntimeUnwindableStub API to the Debugger contract abstraction. |
| src/coreclr/vm/datadescriptor/datadescriptor.inc | Exposes Debugger RgHijackFunction, introduces MemoryRange type descriptor, and adds MaxHijackFunctions global literal. |
| src/coreclr/inc/memoryrange.h | Adds cDAC exposure (cdac_data<MemoryRange>) for MemoryRange field offsets. |
| src/coreclr/debug/ee/debugger.h | Annotates hijack enum constant dependency; exposes hijack table pointer and constant via cdac_data<Debugger>. |
| src/coreclr/debug/di/rsstackwalk.cpp | Avoids fetching current context after unwind when already at end-of-stack. |
| docs/design/datacontracts/StackWalk.md | Updates contract documentation for new StackWalk APIs and aligned, caller-buffer GetContext. |
| docs/design/datacontracts/Debugger.md | Documents IsRuntimeUnwindableStub and the hijack-table globals/data descriptors. |
Copilot's findings
- Files reviewed: 27/27 changed files
- Comments generated: 6
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>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment on lines
+1305
to
+1312
| handleData = new StackWalkHandleData(_target.Contracts.StackWalk, threadData); | ||
| SeedHandleFromNativeContext(handleData, pInternalContextBuffer, isFirst: true); | ||
| *ppSFIHandle = handleData.GetHandle(); | ||
| } | ||
| catch (System.Exception ex) | ||
| { | ||
| hr = ex.HResult; | ||
| } |
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>
Comment on lines
+1316
to
+1318
| uint contextSize = IPlatformAgnosticContext.GetContextForPlatform(_target).Size; | ||
| byte* pLocal = (byte*)NativeMemory.AlignedAlloc(contextSize, IPlatformAgnosticContext.ContextAlignment); | ||
| nuint legacyHandle = 0; |
Comment on lines
+1432
to
+1434
| { | ||
| byte* pLocal = (byte*)NativeMemory.AlignedAlloc(contextSize, IPlatformAgnosticContext.ContextAlignment); | ||
| try |
Comment on lines
1867
to
+1872
| IPlatformAgnosticContext leafCtx = IPlatformAgnosticContext.GetContextForPlatform(_target); | ||
| uint allFlags = leafCtx.AllContextFlags; | ||
| ThreadData threadData = _target.Contracts.Thread.GetThreadData(new TargetPointer(vmThread)); | ||
| byte[] leafContext = _target.Contracts.StackWalk.GetContext(threadData, ThreadContextSource.None, allFlags); | ||
| leafCtx.FillFromBuffer(leafContext); | ||
|
|
||
| byte* pLeaf = (byte*)NativeMemory.AlignedAlloc(leafCtx.Size, IPlatformAgnosticContext.ContextAlignment); | ||
| try |
Comment on lines
1929
to
1933
| { | ||
| uint contextSize = IPlatformAgnosticContext.GetContextForPlatform(_target).Size; | ||
| byte[] localContextBuf = new byte[contextSize]; | ||
| fixed (byte* pLocal = localContextBuf) | ||
| byte* pLocal = (byte*)NativeMemory.AlignedAlloc(contextSize, IPlatformAgnosticContext.ContextAlignment); | ||
| try | ||
| { |
Comment on lines
+350
to
+352
| // CONTEXT requires 16-byte alignment for the OS GetThreadContext path. | ||
| byte* pContext = (byte*)NativeMemory.AlignedAlloc(ctx.Size, Contracts.StackWalkHelpers.IPlatformAgnosticContext.ContextAlignment); | ||
| try |
Comment on lines
+73
to
+75
| // CONTEXT requires 16-byte alignment for the OS GetThreadContext path. | ||
| byte* pContract = (byte*)NativeMemory.AlignedAlloc(contextSize, IPlatformAgnosticContext.ContextAlignment); | ||
| try |
Comment on lines
71
to
89
| @@ -84,7 +84,8 @@ public interface IStackWalk : IContract | |||
| bool IsExceptionHandlingHelperInlinedCallFrame(TargetPointer frameAddress) => throw new NotImplementedException(); | |||
| DebuggerEvalData GetDebuggerEvalData(TargetPointer funcEvalFrameAddress) => throw new NotImplementedException(); | |||
| TargetPointer GetRedirectedContextPointer(ThreadData threadData) => throw new NotImplementedException(); | |||
| byte[] GetContext(ThreadData threadData, ThreadContextSource contextSource, uint contextFlags) => throw new NotImplementedException(); | |||
| int GetContext(ThreadData threadData, ThreadContextSource contextSource, uint contextFlags, Span<byte> contextBuffer) => throw new NotImplementedException(); | |||
| byte[] RetrieveHijackedContext(IStackDataFrameHandle stackDataFrameHandle, bool isUnhandledException) => throw new NotImplementedException(); | |||
| } | |||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
IsRuntimeUnwindableStubDebugger cDAC APIRetrieveHijackedContextStackWalk cDAC APICreateStackWalkthat accepts an arbitrary seed contextTryGetThreadContextHRESULT for more accurate fallback handlingCreateStackWalk,DeleteStackWalk,SetStackWalkCurrentStackFrame,GetStackWalkCurrentStackFrame, andUnwindStackWalkFrameNote to Copilot code revise: Please DO NOT make ANY comments about breaking public APIs!!!