Skip to content

Add --il-offset option to source command for IL offset resolution#323

Merged
richlander merged 5 commits into
richlander:mainfrom
slang25:feature/il-offset-source-resolution
May 29, 2026
Merged

Add --il-offset option to source command for IL offset resolution#323
richlander merged 5 commits into
richlander:mainfrom
slang25:feature/il-offset-source-resolution

Conversation

@slang25
Copy link
Copy Markdown
Contributor

@slang25 slang25 commented May 28, 2026

Summary

Adds an --il-offset option to the source command that resolves method token + IL offset pairs to source file locations using PDB sequence points.

This is useful when working with stacktraces from .NET runtimes that include IL offsets instead of line numbers (e.g., Tizen, or environments where symbols aren't available at runtime). With Switch.System.Diagnostics.StackTrace.ShowILOffsets enabled, stacktraces include entries like:

at MyApp.Program.Main() in MyApp.dll: token 0x6000001+0x5

This option translates that token+offset into the actual source file and line number.

Usage

# Basic usage with a local library
dotnet inspect source --library MyApp.dll --il-offset 0x6000001+0x5

# With a platform library
dotnet inspect source --platform System.Text.Json --il-offset 0x6000004+0x15

# JSON output
dotnet inspect source MyPackage --il-offset 0x6000002+0x1 --json

# Markdown view with full details
dotnet inspect source --library MyApp.dll --il-offset 0x6000001+0x5 -v

Implementation

  • SourceLinkResolver: New ResolveByILOffset() method walks PDB sequence points to find the best matching source line. Works with and without SourceLink (falls back to file path + line when no SourceLink URLs are available).
  • SourceCommand: Early branch in ExecuteAsync skips API extraction (not needed — the token identifies the method directly). Parses and validates the token+offset hex format, rejecting non-MethodDef tokens.
  • Output: Supports oneline (default), markdown (-v), and JSON (--json) output formats via a dedicated SourceILOffsetView and ILOffsetResult.
  • Tests: Parser validation tests for valid and invalid token+offset formats.

Closes #322

slang25 and others added 2 commits May 28, 2026 12:24
Add support for resolving method token + IL offset pairs (e.g., 0x6000001+0x5)
to source file locations using PDB sequence points. This is useful when working
with stacktraces from .NET runtimes that include IL offsets instead of line
numbers (e.g., Tizen or environments without symbol files at runtime).

Usage:
  dotnet inspect source --library MyApp.dll --il-offset 0x6000001+0x5
  dotnet inspect source --platform System.Text.Json --il-offset 0x6000004+0x15
  dotnet inspect source MyPackage --il-offset 0x6000002+0x1 --json

Changes:
- SourceLinkResolver: ResolveByILOffset() walks sequence points to find the
  best matching source line for a given IL offset. Works with and without
  SourceLink (falls back to file path + line only).
- PdbContext/SourceLinkService: pass-through wrappers
- SourceCommand: early branch in ExecuteAsync skips API extraction, parses
  token+offset format, validates MethodDef table, outputs in oneline/markdown/JSON
- SourceILOffsetView: dedicated view model for markdown output
- ILOffsetResult: JSON result type registered with source JSON contexts
- Parser validates hex format and rejects non-MethodDef tokens

Closes richlander#322

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@richlander
Copy link
Copy Markdown
Owner

Thanks. Will take a look.

@richlander
Copy link
Copy Markdown
Owner

Thanks for this — the feature works correctly end to end. I verified IL-offset resolution against PDB sequence points across exact, in-between, and boundary offsets, and the malformed/out-of-range token paths all fail gracefully.

I pushed a small follow-up branch, review/il-offset-improvements (commit 5f852b6), with two optional tidy-ups. Please take them, adapt them, or ignore them — entirely your call.

1. Dedup the resolver. ResolveByILOffset and ResolveByILOffsetDirect were ~50 near-identical lines. I collapsed the shared sequence-point walk into the single static ResolveByILOffsetDirect; the instance method now just enriches the result with SourceLink URLs via record ... with. Same behaviour, net −53 lines. Also switched sp.StartLine != SequencePoint.HiddenLine to !sp.IsHidden to match the convention used elsewhere in the file.

2. Tests for the walk. The parser was already covered, but the sequence-point resolution itself wasn't. Added ILOffsetResolutionTests (against a real PDB) covering exact sequence-point offsets, an in-between offset resolving to the preceding point, and the non-MethodDef / out-of-range null paths.

I left the System.Text.Json full-qualification as-is — it matches the existing style in SourceCommand.cs.

If it's easier than eyeballing the branch, you can pull the commit directly:

git fetch https://github.com/richlander/dotnet-inspect.git review/il-offset-improvements
git cherry-pick 5f852b6

richlander and others added 2 commits May 29, 2026 00:09
Collapse the near-identical ResolveByILOffset / ResolveByILOffsetDirect
methods into a single static sequence-point walk; the instance method now
enriches the result with SourceLink URLs via `with`. Use !sp.IsHidden to
match the rest of the file.

Add ILOffsetResolutionTests covering the walk against a real PDB: exact
sequence-point offsets, an in-between offset resolving to the preceding
point, and the non-MethodDef / out-of-range null paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@slang25
Copy link
Copy Markdown
Contributor Author

slang25 commented May 28, 2026

@richlander those changes make sense, I've pulled them in 🙂

@richlander
Copy link
Copy Markdown
Owner

I'll finish this up tomorrow. The rendering doesn't quite work the same as other commands. I already made some changes. I'll push those in the morning.

@richlander
Copy link
Copy Markdown
Owner

richlander commented May 29, 2026

SourceILOffsetView emitted a single fixed inline field block at every verbosity level — -v:q, -v:n, and -v:d all produced identical output. Every other view in the tool gates content by verbosity and renders structured data as ## sections rather than loose inline fields.

The change: reshape the view to follow the library (LibraryInspectionView) discipline:

Level Output
-v:q compact inline line: Token … | IL Offset … | Matched Offset …
-v:m (default) ## Offset section only
-v:n / -v:d ## Offset + ## Source (file / line / URL)

Source content is reserved for normal+, matching how source <type> reveals detail progressively. --json and --oneline are unchanged. Patch version bumped to 0.7.11.

Pushed to il-offset-sections (commit c0b874f) to pull from.

The IL-offset view emitted one frozen inline field block at every
verbosity level, unlike the rest of the tool. Reshape it to follow the
library-info view's discipline:

  -v:q  → compact inline line (token + offsets only)
  -v:m  → "Offset" section only
  -v:n+ → "Offset" + "Source" (resolved file/line/URL) sections

No loose inline fields dangle above the sections. JSON and --oneline
output are unchanged. Bump patch version to 0.7.11.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@richlander richlander merged commit 9298de9 into richlander:main May 29, 2026
10 checks passed
@richlander
Copy link
Copy Markdown
Owner

Thanks! Published.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Find sources via Method Tokens + IL Offsets

2 participants