public void EmbeddedPortablePdb() { string source = @" using System; class C { public static void Main() { Console.WriteLine(); } } "; var c = CreateCompilationWithMscorlib(Parse(source, "foo.cs"), options: TestOptions.DebugDll); var peBlob = c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.Embedded).WithPdbFilePath(@"a/b/c/d.pdb")); using (var peReader = new PEReader(peBlob)) { var entries = peReader.ReadDebugDirectory(); AssertEx.Equal(new[] { DebugDirectoryEntryType.CodeView, DebugDirectoryEntryType.EmbeddedPortablePdb }, entries.Select(e => e.Type)); var codeView = entries[0]; var embedded = entries[1]; // EmbeddedPortablePdb entry: Assert.Equal(0x0100, embedded.MajorVersion); Assert.Equal(0x0100, embedded.MinorVersion); Assert.Equal(0u, embedded.Stamp); BlobContentId pdbId; using (var embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embedded)) { var mdReader = embeddedMetadataProvider.GetMetadataReader(); AssertEx.Equal(new[] { "foo.cs" }, mdReader.Documents.Select(doc => mdReader.GetString(mdReader.GetDocument(doc).Name))); pdbId = new BlobContentId(mdReader.DebugMetadataHeader.Id); } // CodeView entry: var codeViewData = peReader.ReadCodeViewDebugDirectoryData(codeView); Assert.Equal(0x0100, codeView.MajorVersion); Assert.Equal(0x504D, codeView.MinorVersion); Assert.Equal(pdbId.Stamp, codeView.Stamp); Assert.Equal(pdbId.Guid, codeViewData.Guid); Assert.Equal("d.pdb", codeViewData.Path); } }
private static OpenedReader TryOpenReaderFromEmbeddedPdb(PEReader peReader, DebugDirectoryEntry embeddedPdbEntry) { OpenedReader result = null; MetadataReaderProvider provider = null; try { // TODO: We might want to cache this provider globally (across stack traces), // since decompressing embedded PDB takes some time. provider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdbEntry); result = new OpenedReader(provider, provider.GetMetadataReader()); } catch (Exception e) when (e is BadImageFormatException || e is IOException) { return null; } finally { if (result == null) { provider?.Dispose(); } } return result; }
public void EmbeddedSource_InEmbeddedPdb() { string source = @" using System; class C { public static void Main() { Console.WriteLine(); } } "; var tree = Parse(source, "f:/build/foo.cs"); var c = CreateCompilationWithMscorlib(tree, options: TestOptions.DebugDll); var pdbStream = new MemoryStream(); var peBlob = c.EmitToArray( EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.Embedded), embeddedTexts: new[] { EmbeddedText.FromSource(tree.FilePath, tree.GetText()) }); pdbStream.Position = 0; using (var peReader = new PEReader(peBlob)) { var embeddedEntry = peReader.ReadDebugDirectory().Single(e => e.Type == DebugDirectoryEntryType.EmbeddedPortablePdb); using (var embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedEntry)) { var pdbReader = embeddedMetadataProvider.GetMetadataReader(); var embeddedSource = (from documentHandle in pdbReader.Documents let document = pdbReader.GetDocument(documentHandle) select new { FilePath = pdbReader.GetString(document.Name), Text = pdbReader.GetEmbeddedSource(documentHandle) }).Single(); Assert.Equal(embeddedSource.FilePath, "f:/build/foo.cs"); Assert.Equal(source, embeddedSource.Text.ToString()); } } }
public void SourceLink_Embedded() { string source = @" using System; class C { public static void Main() { Console.WriteLine(); } } "; var sourceLinkBlob = Encoding.UTF8.GetBytes(@" { ""documents"": { ""f:/build/*"" : ""https://raw.githubusercontent.com/my-org/my-project/1111111111111111111111111111111111111111/*"" } } "); var c = CreateCompilationWithMscorlib(Parse(source, "f:/build/foo.cs"), options: TestOptions.DebugDll); var peBlob = c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.Embedded), sourceLinkStream: new MemoryStream(sourceLinkBlob)); using (var peReader = new PEReader(peBlob)) { var embeddedEntry = peReader.ReadDebugDirectory().Single(e => e.Type == DebugDirectoryEntryType.EmbeddedPortablePdb); using (var embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedEntry)) { var pdbReader = embeddedMetadataProvider.GetMetadataReader(); var actualBlob = (from cdiHandle in pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition) let cdi = pdbReader.GetCustomDebugInformation(cdiHandle) where pdbReader.GetGuid(cdi.Kind) == PortableCustomDebugInfoKinds.SourceLink select pdbReader.GetBlobBytes(cdi.Value)).Single(); AssertEx.Equal(sourceLinkBlob, actualBlob); } } }