Add cdac-dump-inspect script for ad-hoc dump analysis#127031
Merged
max-charlamb merged 5 commits intodotnet:mainfrom Apr 24, 2026
Merged
Add cdac-dump-inspect script for ad-hoc dump analysis#127031max-charlamb merged 5 commits intodotnet:mainfrom
max-charlamb merged 5 commits intodotnet:mainfrom
Conversation
Contributor
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an ad-hoc developer tool under src/native/managed/cdac/scripts to inspect .NET crash dumps using ClrMD + the cDAC reader, intended to quickly validate contract descriptor / thread / stack-walk behavior without WinDbg/SOS.
Changes:
- Introduces
cdac-dump-inspectconsole app (descriptor,threads,stackscommands) that loads a dump via ClrMD and queries cDAC contracts. - Adds a PowerShell wrapper to build and run the tool using the repo-local
.dotnet. - Adds scripts-area documentation describing prerequisites, usage, and examples.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/native/managed/cdac/scripts/cdac-dump-inspect.ps1 | Wrapper to build/run the inspector using the repo-local SDK. |
| src/native/managed/cdac/scripts/cdac-dump-inspect.csproj | New tool project referencing cDAC reader/contracts and ClrMD. |
| src/native/managed/cdac/scripts/cdac-dump-inspect.cs | Main implementation for descriptor/thread/stack inspection. |
| src/native/managed/cdac/scripts/README.md | Usage docs for the scripts folder and the new tool. |
steveisok
approved these changes
Apr 17, 2026
Add a developer tool for inspecting .NET crash dumps using ClrMD and the cDAC. Supports three commands: - descriptor: print the full contract descriptor (contracts, types, globals) - threads: list managed threads with OS ID and state - stacks: walk managed stacks showing instruction pointers and method descriptors Includes a PowerShell wrapper for easy invocation, README documentation, cycle detection for corrupt thread lists, and descriptor size validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The GetTargetThreadContextDelegate follows HRESULT convention where 0 means success. Returning buffer.Length (912) caused TryGetThreadContext to treat every call as a failure, breaking stack walking. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add Test-Path check for repo-local SDK in PowerShell wrapper - Fix relative link to contract descriptor doc (off by one level) - Validate DataReader.Read return values for short/failed reads - Add null check for descriptor pointer - Print full exception (ex.ToString()) instead of just ex.Message Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use System.CommandLine for proper CLI argument parsing - Split into separate files: Program.cs, DescriptorCommand.cs, ThreadsCommand.cs, StacksCommand.cs, DumpHelpers.cs, ParsedDescriptor.cs - Add recursive sub-descriptor traversal and merge conflict detection - Resolve indirect globals through pointer data with dereferenced values - Fix read callback to return 0/-1 instead of byte count - Fix write callback to return -1 instead of throwing - Use explicit module allow-list with NativeAOT fallback - Fall back to dotnet on PATH when repo-local SDK is unavailable - Address all PR review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8c301e2 to
a1caf96
Compare
- Check export before FileName to handle modules with null FileName - Validate magic bytes (DNCCDAC) in TryReadDescriptor - Cap pointerDataCount at 1024 and check null pointerDataAddr - Use ulong arithmetic for pointer data offset to prevent overflow - Validate full JSON read and catch parse exceptions gracefully - Remove misleading pointer dereference from indirect global display Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Note
This PR was authored with the help of Copilot.
Summary
Add a developer tool for inspecting .NET crash dumps using ClrMD and the cDAC (contract-based Data Access). This provides a quick way to verify cDAC functionality against real dumps without needing WinDbg or SOS.
Commands
descriptorthreadsstacksUsage
Or directly with dotnet run:
Architecture
The tool uses
System.CommandLinefor CLI parsing (matchingcdac-build-toolconventions) and is split into separate files for extensibility:Program.csRootCommandand subcommand registrationDescriptorCommand.csdescriptorcommand — recursive sub-descriptor traversal, merge conflict detectionThreadsCommand.csthreadscommandStacksCommand.csstackscommandDumpHelpers.csFindContractDescriptor,CreateCdacTargetParsedDescriptor.csParsedDescriptorrecord typecdac-dump-inspect.ps1dotneton PATHREADME.mdKey features
-> *0x...)DotNetRuntimeContractDescriptorexport when not in a known CoreCLR moduledotneton PATH, not just the repo-local SDK