Support embedded portable PDBs for managed symbol resolution#2434
Open
JeremyKuhne wants to merge 3 commits into
Open
Support embedded portable PDBs for managed symbol resolution#2434JeremyKuhne wants to merge 3 commits into
JeremyKuhne wants to merge 3 commits into
Conversation
Managed assemblies built with <DebugType>embedded</DebugType> carry their portable PDB inside the PE image rather than in a standalone .pdb file. Previously SymbolReader could not read these, so source/line lookup failed for such modules. Add the ability to open an embedded portable PDB: - SymbolReader.OpenEmbeddedPortablePdb reads the EmbeddedPortablePdb debug-directory entry from a module and returns a PortableSymbolModule. Results are cached under a key suffixed so they cannot collide with standalone-PDB cache entries. - SymbolReader.OpenSymbolFileForModuleFile is a module-oriented entry point that prefers a standalone PDB and falls back to an embedded portable PDB. - PortableSymbolModule gains a constructor that takes a MetadataReaderProvider (which owns its own backing memory). - TraceLog.OpenPdbForModuleFile falls back to the module's embedded portable PDB when the on-disk module matches the trace and no standalone PDB exists. Tests: add an EmbeddedPdbTestApp fixture (built with embedded PDBs) and cover the happy path, caching, not-embedded/missing-file cases, the module-oriented entry point (embedded and standalone), and the end-to-end TraceLog fallback path. All run cross-platform on net462 and net8.0.
Member
Author
|
Also tried the nupkg in a project where I need this support and it worked fine. |
In Release the C# compiler optimizes EmbeddedTarget.Add, shifting its first sequence point from the 'int sum = a + b;' line to the 'return' line, so the source-line assertions failed in the Release CI leg. Pin Optimize=false on the fixture so its emitted sequence points are stable regardless of the build configuration.
brianrob
reviewed
Jun 3, 2026
Member
brianrob
left a comment
There was a problem hiding this comment.
I appreciate you putting this together. A couple of comments below.
| if (TraceModuleUnchanged(moduleFile, symReader.m_log)) | ||
| { | ||
| pdbFileName = symReader.FindSymbolFilePathForModule(moduleFile.FilePath); | ||
|
|
Member
There was a problem hiding this comment.
This will work for traces that are captured on the same machine before the binaries are removed or overwritten. Should we be looking to capture the PDBs during trace merge so that anyone who captures a trace where binaries have embedded PDBs will have them extracted and zipped up with the etl (ala NGEN PDBs from .NET Framework)?
Member
Author
There was a problem hiding this comment.
Yeah, I think so. I can do a follow up that explores that if you'd like. :)
Per PR review: this wrapper was called only from tests, and TraceLog.OpenPdbForModuleFile already provides the standalone-then-embedded fallback for the trace path. Removed it and its three dedicated tests, keeping OpenEmbeddedPortablePdb (the building block TraceLog uses).
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.
Summary
Managed assemblies built with
<DebugType>embedded</DebugType>carry their portable PDB inside the PE image rather than in a standalone.pdbfile. PreviouslySymbolReadercould not read these, so source/line lookup failed for such modules. This PR adds the ability to read embedded portable PDBs.Changes
SymbolReader.OpenEmbeddedPortablePdb— reads theEmbeddedPortablePdbdebug-directory entry from a module and returns aPortableSymbolModule. Results are cached under a key suffixed so they cannot collide with standalone-PDB cache entries.PortableSymbolModule— gains a constructor that takes aMetadataReaderProvider(which owns its own backing memory, so the module survives disposal of thePEReader/FileStreamused to open it).TraceLog.OpenPdbForModuleFile— falls back to the module's embedded portable PDB when the on-disk module matches the trace and no standalone PDB exists.Tests
Adds an
EmbeddedPdbTestAppfixture (built with<DebugType>embedded</DebugType>) and covers:PEReaderis disposed,TraceLogfallback path.All tests run cross-platform on net462 and net8.0 in Debug.