Skip to content

Add cdac-dump-inspect script for ad-hoc dump analysis#127031

Merged
max-charlamb merged 5 commits intodotnet:mainfrom
max-charlamb:cdac-dump-inspect-script
Apr 24, 2026
Merged

Add cdac-dump-inspect script for ad-hoc dump analysis#127031
max-charlamb merged 5 commits intodotnet:mainfrom
max-charlamb:cdac-dump-inspect-script

Conversation

@max-charlamb
Copy link
Copy Markdown
Member

@max-charlamb max-charlamb commented Apr 16, 2026

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

Command Description
descriptor Print the full contract descriptor: version, baseline, contracts, types with fields, globals, and sub-descriptors. Recursively follows sub-descriptors and detects merge conflicts.
threads List managed threads with OS ID, thread state, and address
stacks Walk managed stacks showing instruction pointers and method descriptors

Usage

# Via the PowerShell wrapper (auto-builds)
./src/native/managed/cdac/scripts/cdac-dump-inspect.ps1 descriptor <dump-path>
./src/native/managed/cdac/scripts/cdac-dump-inspect.ps1 threads <dump-path>
./src/native/managed/cdac/scripts/cdac-dump-inspect.ps1 stacks <dump-path> -Release

Or directly with dotnet run:

dotnet run --project src/native/managed/cdac/scripts/cdac-dump-inspect.csproj -- descriptor <dump-path>

Architecture

The tool uses System.CommandLine for CLI parsing (matching cdac-build-tool conventions) and is split into separate files for extensibility:

File Description
Program.cs Entry point with RootCommand and subcommand registration
DescriptorCommand.cs descriptor command — recursive sub-descriptor traversal, merge conflict detection
ThreadsCommand.cs threads command
StacksCommand.cs stacks command
DumpHelpers.cs Shared utilities: FindContractDescriptor, CreateCdacTarget
ParsedDescriptor.cs ParsedDescriptor record type
cdac-dump-inspect.ps1 PowerShell wrapper — prefers repo-local SDK, falls back to dotnet on PATH
README.md Documentation

Key features

  • Recursive sub-descriptor support: Follows sub-descriptor pointers through the pointer data array, printing each descriptor's contents separately
  • Merge conflict detection: After displaying all descriptors, detects duplicate contracts, types, and globals across descriptors
  • Indirect global resolution: Shows both the pointer data address and the dereferenced value (-> *0x...)
  • NativeAOT support: Falls back to scanning all modules for the DotNetRuntimeContractDescriptor export when not in a known CoreCLR module
  • Flexible SDK: Works with any dotnet on PATH, not just the repo-local SDK

@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-inspect console app (descriptor, threads, stacks commands) 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.

Comment thread src/native/managed/cdac/scripts/cdac-dump-inspect.ps1
Comment thread src/native/managed/cdac/scripts/README.md Outdated
Comment thread src/native/managed/cdac/scripts/cdac-dump-inspect.cs Outdated
Comment thread src/native/managed/cdac/scripts/cdac-dump-inspect.cs Outdated
Comment thread src/native/managed/cdac/scripts/cdac-dump-inspect.cs Outdated
@steveisok steveisok self-requested a review April 17, 2026 02:46
@max-charlamb max-charlamb marked this pull request as ready for review April 17, 2026 19:04
Copilot AI review requested due to automatic review settings April 17, 2026 19:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

Comment thread src/native/managed/cdac/scripts/cdac-dump-inspect.cs Outdated
Comment thread src/native/managed/cdac/scripts/cdac-dump-inspect.cs Outdated
Comment thread src/native/managed/cdac/scripts/cdac-dump-inspect.ps1 Outdated
Comment thread src/native/managed/cdac/scripts/cdac-dump-inspect.cs Outdated
Comment thread src/native/managed/cdac/scripts/cdac-dump-inspect.cs Outdated
Max Charlamb and others added 4 commits April 21, 2026 15:18
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>
Copilot AI review requested due to automatic review settings April 22, 2026 21:23
@max-charlamb max-charlamb force-pushed the cdac-dump-inspect-script branch from 8c301e2 to a1caf96 Compare April 22, 2026 21:23
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 8 comments.

Comment thread src/native/managed/cdac/scripts/DumpHelpers.cs Outdated
Comment thread src/native/managed/cdac/scripts/DescriptorCommand.cs
Comment thread src/native/managed/cdac/scripts/DescriptorCommand.cs
Comment thread src/native/managed/cdac/scripts/DescriptorCommand.cs Outdated
Comment thread src/native/managed/cdac/scripts/DescriptorCommand.cs Outdated
Comment thread src/native/managed/cdac/scripts/DescriptorCommand.cs Outdated
Comment thread src/native/managed/cdac/scripts/README.md
Comment thread src/native/managed/cdac/scripts/README.md
- 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>
@max-charlamb max-charlamb merged commit cdd67ad into dotnet:main Apr 24, 2026
56 of 59 checks passed
@max-charlamb max-charlamb deleted the cdac-dump-inspect-script branch April 24, 2026 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants