Skip to content

feat: Portable PDB (BSJB) debug identity + multi-target net10.0#4

Open
bobbyg603 wants to merge 1 commit into
mainfrom
feat/portable-pdb-identity
Open

feat: Portable PDB (BSJB) debug identity + multi-target net10.0#4
bobbyg603 wants to merge 1 commit into
mainfrom
feat/portable-pdb-identity

Conversation

@bobbyg603

Copy link
Copy Markdown
Member

What

PDBFile now transparently extracts a Portable PDB (ECMA-335 BSJB) debug identity — the {GUID}{age} symbol-server key — in addition to the existing MSF/CodeView PDB and PE support. The identity is the 16-byte GUID prefix of the metadata "PDB id" (DebugMetadataHeader.Id) with age 1 (Roslyn's fixed RSDS age for portable PDBs), formatted exactly as a System.Guid("N") + age, so it matches the key a dump's CodeView record resolves to.

Why

The BugSplat backend keys uploaded symbols into its symsrv store with PdbLibrary.PDBFile(...).GUID.Value(). Portable PDBs (the format .NET Core / modern-SDK app assemblies ship) previously threw on the MSF signature check, so they were skipped and never indexed — meaning bugsplat-cdb's managed line resolution for .NET Core crashes couldn't find the app PDB. This closes that gap with no change to the indexer call site.

How

  • Multi-targeted netstandard2.0;net10.0. Portable identity uses in-box System.Reflection.Metadata, guarded #if NET, so it compiles only on the net10.0 flavor. No package reference is added on any target; the netstandard2.0 flavor stays pure BCL (MSF + PE only), preserving cross-platform use.
  • Added a golden test against a real portable PDB fixture, asserting the key equals the store directory it lives under (0023F679…B6721).

Version bumped to 1.2.0. Verified: dotnet test — 6/6 pass on net10.0.

PDBFile now transparently reads a Portable PDB's debug identity (the
{GUID}{age} symbol-server key) alongside MSF/CodeView PDBs and PE images,
so a store keyed by PdbLibrary indexes .NET Core / modern-SDK app PDBs
under the same key a dump's CodeView record names. The identity is the
16-byte GUID prefix of the metadata "PDB id" with age 1 (Roslyn's fixed
RSDS age for portable PDBs).

Multi-targeted netstandard2.0;net10.0: portable identity uses in-box
System.Reflection.Metadata under #if NET (net10.0), so no package
reference is added and the netstandard2.0 flavor stays pure BCL
(MSF + PE only). Adds a golden test against a real portable PDB.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 20:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds Portable PDB (ECMA-335 “BSJB”) debug-identity extraction to PDBFile and updates the library to multi-target so Portable PDB parsing is available on modern .NET while keeping the netstandard2.0 surface area/package dependencies unchanged.

Changes:

  • Multi-target PdbLibrary as netstandard2.0;net10.0 and bump package version to 1.2.0.
  • Detect Portable PDBs via the BSJB magic and extract {GUID}{age} from portable PDB metadata (age fixed at 1).
  • Add a golden unit test validating the portable PDB store key for a real fixture.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

File Description
UnitTestPdbLibrary/PdbLibraryTests.cs Adds a portable-PDB fixture test asserting the {GUID}{age} store key.
PdbLibrary/PdbLibrary.csproj Multi-targets netstandard2.0 + net10.0 and updates package metadata/version.
PdbLibrary/PdbLibrary.cs Implements Portable PDB detection + identity extraction via System.Reflection.Metadata on .NET targets.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread PdbLibrary/PdbLibrary.cs
Comment on lines +406 to +416
var header = reader.DebugMetadataHeader;
if (header == null)
{
throw new Exception("Not a portable PDB: file has no debug metadata header");
}

var idBlob = header.Id; // 20-byte PDB id: 16-byte GUID + 4-byte stamp
if (idBlob.Length < 16)
{
throw new Exception($"Portable PDB id too short: {idBlob.Length} bytes");
}
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.

3 participants