public void CreateFrom_Errors() { Assert.Throws <ArgumentException>(() => DebugInformationReaderProvider.CreateFromStream(new TestStream(canRead: false, canSeek: true, canWrite: true))); Assert.Throws <ArgumentException>(() => DebugInformationReaderProvider.CreateFromStream(new TestStream(canRead: true, canSeek: false, canWrite: true))); Assert.Throws <ArgumentNullException>(() => DebugInformationReaderProvider.CreateFromStream(null)); Assert.Throws <ArgumentNullException>(() => DebugInformationReaderProvider.CreateFromMetadataReader(null)); }
/// <summary> /// Opens PDB produced by the compiler. /// The caller must dispose the returned <see cref="DebugInformationReaderProvider"/>. /// </summary> /// <returns> /// Instance of <see cref="DebugInformationReaderProvider"/>, which owns the opened PDB and must be disposed once the caller is done reading the data, /// or null if PDB is not available. /// </returns> /// <exception cref="BadImageFormatException">Invalid format of the PDB or assembly data.</exception> /// <exception cref="InvalidOperationException">The stream returned by <see cref="OpenPdbStreamChecked"/> or <see cref="OpenAssemblyStreamChecked"/> does not support read and seek operations.</exception> /// <exception cref="Exception">Error while reading assembly data.</exception> /// <remarks> /// If a separate PDB stream is not available (<see cref="OpenPdbStreamChecked"/> returns null) opens the PDB embedded in the assembly, if present. /// </remarks> public virtual DebugInformationReaderProvider?OpenPdb() { var pdbStream = OpenPdbStreamChecked(); if (pdbStream != null) { return(DebugInformationReaderProvider.CreateFromStream(pdbStream)); } // check for embedded PDB var peStream = OpenAssemblyStreamChecked(); if (peStream != null) { using var peReader = new PEReader(peStream); var embeddedPdbEntry = peReader .ReadDebugDirectory() .FirstOrDefault(e => e.Type == DebugDirectoryEntryType.EmbeddedPortablePdb); if (embeddedPdbEntry.DataSize != 0) { return(DebugInformationReaderProvider.CreateFromMetadataReader( peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdbEntry) )); } } return(null); }
public void DebugInfo(DebugInformationFormat format, bool useSymReader) { var source = @" using System; delegate void D(); class C { public static void Main() { int x = 1; D d = () => Console.Write(x); d(); } } "; var compilation = CSharpTestBase.CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll, sourceFileName: "/a/c.cs"); var pdbStream = new MemoryStream(); compilation.EmitToArray(new EmitOptions(debugInformationFormat: format), pdbStream: pdbStream); pdbStream.Position = 0; DebugInformationReaderProvider provider; EditAndContinueMethodDebugInfoReader reader; if (format == DebugInformationFormat.PortablePdb && useSymReader) { var pdbStreamCom = SymUnmanagedStreamFactory.CreateStream(pdbStream); var metadataImportProvider = new DummyMetadataImportProvider(); Assert.Equal(0, new SymBinder().GetReaderFromPdbStream(metadataImportProvider, pdbStreamCom, out var symReader)); reader = EditAndContinueMethodDebugInfoReader.Create((ISymUnmanagedReader5)symReader, version: 1); } else { provider = DebugInformationReaderProvider.CreateFromStream(pdbStream); reader = provider.CreateEditAndContinueMethodDebugInfoReader(); } // Main method var debugInfo = reader.GetDebugInfo(MetadataTokens.MethodDefinitionHandle(5)); Assert.Equal(0, debugInfo.GetMethodOrdinal()); AssertEx.Equal(new[] { "Offset=0 Ordinal=0 Kind=LambdaDisplayClass", "Offset=33 Ordinal=0 Kind=UserDefined" }, debugInfo.InspectLocalSlots()); AssertEx.Equal(new[] { "Offset=43 Id=0#0 Closure=0" }, debugInfo.InspectLambdas()); AssertEx.Equal(new[] { "Offset=0 Id=0#0" }, debugInfo.InspectClosures()); var localSig = reader.GetLocalSignature(MetadataTokens.MethodDefinitionHandle(5)); Assert.Equal(MetadataTokens.StandaloneSignatureHandle(1), localSig); // method without debug information: debugInfo = reader.GetDebugInfo(MetadataTokens.MethodDefinitionHandle(1)); Assert.Equal(-1, debugInfo.GetMethodOrdinal()); Assert.Null(debugInfo.InspectLocalSlots()); Assert.Null(debugInfo.InspectLambdas()); Assert.Null(debugInfo.InspectClosures()); localSig = reader.GetLocalSignature(MetadataTokens.MethodDefinitionHandle(1)); Assert.Equal(default, localSig);
public override DebugInformationReaderProvider?OpenPdb() { var assemblyStream = OpenAssemblyStream(); if (assemblyStream == null) { return(null); } // find associated PDB string pdbPath; using (var peReader = new PEReader(assemblyStream)) { var debugDirectory = peReader.ReadDebugDirectory(); var embeddedPdbEntry = debugDirectory.FirstOrDefault( e => e.Type == DebugDirectoryEntryType.EmbeddedPortablePdb ); if (embeddedPdbEntry.DataSize != 0) { return(DebugInformationReaderProvider.CreateFromMetadataReader( peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdbEntry) )); } var codeViewEntry = debugDirectory.FirstOrDefault( e => e.Type == DebugDirectoryEntryType.CodeView ); if (codeViewEntry.DataSize == 0) { return(null); } pdbPath = peReader.ReadCodeViewDebugDirectoryData(codeViewEntry).Path; } // First try to use the full path as specified in the PDB, then look next to the assembly. var pdbStream = TryOpenFileStream(pdbPath) ?? TryOpenFileStream( Path.Combine( Path.GetDirectoryName(AssemblyFilePath) !, PathUtilities.GetFileName(pdbPath) ) ); return((pdbStream != null) ? DebugInformationReaderProvider.CreateFromStream(pdbStream) : null); }