public IList <Decompiler.DebugInfo.SequencePoint> GetSequencePoints(MethodDefinitionHandle method) { var metadata = provider.GetMetadataReader(); var debugInfo = metadata.GetMethodDebugInformation(method); var sequencePoints = new List <Decompiler.DebugInfo.SequencePoint>(); foreach (var point in debugInfo.GetSequencePoints()) { string documentFileName; if (!point.Document.IsNil) { var document = metadata.GetDocument(point.Document); documentFileName = metadata.GetString(document.Name); } else { documentFileName = ""; } sequencePoints.Add(new Decompiler.DebugInfo.SequencePoint() { Offset = point.Offset, StartLine = point.StartLine, StartColumn = point.StartColumn, EndLine = point.EndLine, EndColumn = point.EndColumn, DocumentUrl = documentFileName }); } return(sequencePoints); }
/// <summary> /// Returns the portable PDB reader for the assembly path /// </summary> /// <param name="assemblyPath">file path of the assembly or null</param> /// <param name="loadedPeAddress">loaded PE image address or zero</param> /// <param name="loadedPeSize">loaded PE image size</param> /// <param name="inMemoryPdbAddress">in memory PDB address or zero</param> /// <param name="inMemoryPdbSize">in memory PDB size</param> /// <param name="reader">returns the reader</param> /// <returns>reader</returns> private MetadataReader GetReader(string assemblyPath, IntPtr loadedPeAddress, int loadedPeSize, IntPtr inMemoryPdbAddress, int inMemoryPdbSize) { if (loadedPeAddress != IntPtr.Zero) { Tuple <MetadataReaderProvider, MetadataReader> tuple; if (_readerCache.TryGetValue(loadedPeAddress, out tuple)) { return(tuple.Item2); } } MetadataReaderProvider provider = null; MetadataReader reader = null; if (assemblyPath != null) { uint stamp; int age; Guid guid; string pdbName = GetPdbPathFromPeStream(assemblyPath, loadedPeAddress, loadedPeSize, out age, out guid, out stamp); if (pdbName != null && File.Exists(pdbName)) { Stream pdbStream = File.OpenRead(pdbName); provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream); MetadataReader rdr = provider.GetMetadataReader(); // Validate that the PDB matches the assembly version if (age == 1 && IdEquals(rdr.DebugMetadataHeader.Id, guid, stamp)) { reader = rdr; } else { provider.Dispose(); provider = null; } } } else if (inMemoryPdbAddress != IntPtr.Zero && inMemoryPdbSize > 0) { unsafe { provider = MetadataReaderProvider.FromPortablePdbImage((byte *)inMemoryPdbAddress.ToPointer(), inMemoryPdbSize); reader = provider.GetMetadataReader(); } } if (reader != null && loadedPeAddress != IntPtr.Zero) { _readerCache.Add(loadedPeAddress, Tuple.Create(provider, reader)); } return(reader); }
private unsafe static OpenedReader TryOpenReaderForInMemoryPdb(IntPtr inMemoryPdbAddress, int inMemoryPdbSize) { Debug.Assert(inMemoryPdbAddress != IntPtr.Zero); // quick check to avoid throwing exceptions below in common cases: const uint ManagedMetadataSignature = 0x424A5342; if (inMemoryPdbSize < sizeof(uint) || *(uint *)inMemoryPdbAddress != ManagedMetadataSignature) { // not a Portable PDB return(null); } OpenedReader result = null; MetadataReaderProvider provider = null; try { provider = MetadataReaderProvider.FromMetadataImage((byte *)inMemoryPdbAddress, inMemoryPdbSize); result = new OpenedReader(provider, provider.GetMetadataReader()); } catch (BadImageFormatException) { return(null); } finally { if (result == null) { provider?.Dispose(); } } return(result); }
/// <summary> /// Constructs new assembly debug information. /// </summary> /// <param name="assembly">The referenced assembly.</param> /// <param name="fileName">The associated PDB file.</param> internal AssemblyDebugInformation(Assembly assembly, string fileName) { Assembly = assembly; modules = assembly.GetModules(); using (var pdbFileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { metadataReaderProvider = MetadataReaderProvider.FromPortablePdbStream( pdbFileStream, MetadataStreamOptions.PrefetchMetadata); MetadataReader = metadataReaderProvider.GetMetadataReader(); } var methodDebugInformationEnumerator = MetadataReader.MethodDebugInformation.GetEnumerator(); while (methodDebugInformationEnumerator.MoveNext()) { var methodDebugRef = methodDebugInformationEnumerator.Current; var methodDefinitionHandle = methodDebugRef.ToDefinitionHandle(); var metadataToken = MetadataTokens.GetToken(methodDefinitionHandle); if (TryResolveMethod(metadataToken, out MethodBase method)) { debugInformation.Add(method, new MethodDebugInformation(this, method, methodDebugRef)); } } }
public bool EmbeddedPortablePdbHasLocalSource(string module, out string firstNotFoundDocument) { firstNotFoundDocument = ""; using (Stream moduleStream = _fileSystem.OpenRead(module)) using (var peReader = new PEReader(moduleStream)) { foreach (DebugDirectoryEntry entry in peReader.ReadDebugDirectory()) { if (entry.Type == DebugDirectoryEntryType.EmbeddedPortablePdb) { using (MetadataReaderProvider embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(entry)) { MetadataReader metadataReader = embeddedMetadataProvider.GetMetadataReader(); var matchingResult = MatchDocumentsWithSources(metadataReader); if (!matchingResult.allDocumentsMatch) { firstNotFoundDocument = matchingResult.notFoundDocument; return(false); } } } } } // If we don't have EmbeddedPortablePdb entry return true, for instance empty dll // We should call this method only on embedded pdb module return(true); }
public bool PortablePdbHasLocalSource(string module, out string firstNotFoundDocument) { firstNotFoundDocument = ""; using (var moduleStream = File.OpenRead(module)) using (var peReader = new PEReader(moduleStream)) { foreach (var entry in peReader.ReadDebugDirectory()) { if (entry.Type == DebugDirectoryEntryType.CodeView) { var codeViewData = peReader.ReadCodeViewDebugDirectoryData(entry); using FileStream pdbStream = new FileStream(codeViewData.Path, FileMode.Open); using MetadataReaderProvider metadataReaderProvider = MetadataReaderProvider.FromPortablePdbStream(pdbStream); MetadataReader metadataReader = metadataReaderProvider.GetMetadataReader(); foreach (DocumentHandle docHandle in metadataReader.Documents) { Document document = metadataReader.GetDocument(docHandle); string docName = metadataReader.GetString(document.Name); // We verify all docs and return false if not all are present in local // We could have false negative if doc is not a source // Btw check for all possible extension could be weak approach if (!_fileSystem.Exists(docName)) { firstNotFoundDocument = docName; return(false); } } } } } return(true); }
/// <summary> /// Constructs new assembly debug information. /// </summary> /// <param name="assembly">The referenced assembly.</param> /// <param name="pdbStream"> /// The associated PDB stream (hast to be kept open). /// </param> internal AssemblyDebugInformation(Assembly assembly, Stream pdbStream) { Assembly = assembly; Modules = ImmutableArray.Create(assembly.GetModules()); readerProvider = MetadataReaderProvider.FromPortablePdbStream( pdbStream, MetadataStreamOptions.Default); MetadataReader = readerProvider.GetMetadataReader(); foreach (var methodHandle in MetadataReader.MethodDebugInformation) { var definitionHandle = methodHandle.ToDefinitionHandle(); var metadataToken = MetadataTokens.GetToken(definitionHandle); if (TryResolveMethod(metadataToken, out MethodBase method)) { debugInformation.Add( method, new MethodDebugInformation( this, method, definitionHandle)); } } }
public static bool EmbeddedPortablePdbHasLocalSource(string module) { using (FileStream moduleStream = File.OpenRead(module)) using (var peReader = new PEReader(moduleStream)) { foreach (DebugDirectoryEntry entry in peReader.ReadDebugDirectory()) { if (entry.Type == DebugDirectoryEntryType.EmbeddedPortablePdb) { using (MetadataReaderProvider embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(entry)) { MetadataReader metadataReader = embeddedMetadataProvider.GetMetadataReader(); foreach (DocumentHandle docHandle in metadataReader.Documents) { Document document = metadataReader.GetDocument(docHandle); string docName = metadataReader.GetString(document.Name); // We verify all docs and return false if not all are present in local // We could have false negative if doc is not a source // Btw check for all possible extension could be weak approach if (!File.Exists(docName)) { return(false); } } } } } } // If we don't have EmbeddedPortablePdb entry return true, for instance empty dll // We should call this method only on embedded pdb module return(true); }
public static void ReadPdbDocuments(string pdbPath) { // Open Portable PDB file using var fs = new FileStream(pdbPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using MetadataReaderProvider provider = MetadataReaderProvider.FromPortablePdbStream(fs); MetadataReader reader = provider.GetMetadataReader(); // Display information about documents in each MethodDebugInformation table entry foreach (MethodDebugInformationHandle h in reader.MethodDebugInformation) { MethodDebugInformation mdi = reader.GetMethodDebugInformation(h); if (mdi.Document.IsNil) { continue; } int token = MetadataTokens.GetToken(h); Console.WriteLine($"MethodDebugInformation 0x{token.ToString("X")}"); Document doc = reader.GetDocument(mdi.Document); Console.WriteLine($"File: {ReadDocumentPath(reader, doc)}"); Guid guidLang = reader.GetGuid(doc.Language); Console.WriteLine($"Language: {guidLang}"); Guid guidHashAlg = reader.GetGuid(doc.HashAlgorithm); Console.WriteLine($"Hash algorithm: {guidHashAlg}"); Console.WriteLine(); } }
public unsafe void TryOpenAssociatedPortablePdb_EmbeddedUnused() { var peStream = new MemoryStream(PortablePdbs.DocumentsEmbeddedDll); using (var reader = new PEReader(peStream)) { using (MetadataReaderProvider embeddedProvider = reader.ReadEmbeddedPortablePdbDebugDirectoryData(reader.ReadDebugDirectory()[2])) { var embeddedReader = embeddedProvider.GetMetadataReader(); var embeddedBytes = new BlobReader(embeddedReader.MetadataPointer, embeddedReader.MetadataLength).ReadBytes(embeddedReader.MetadataLength); string pathQueried = null; Func <string, Stream> streamProvider = p => { Assert.Null(pathQueried); pathQueried = p; return(new MemoryStream(embeddedBytes)); }; MetadataReaderProvider pdbProvider; string pdbPath; Assert.True(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), streamProvider, out pdbProvider, out pdbPath)); Assert.Equal(Path.Combine("pedir", "Documents.Embedded.pdb"), pathQueried); Assert.Equal(Path.Combine("pedir", "Documents.Embedded.pdb"), pdbPath); var pdbReader = pdbProvider.GetMetadataReader(); Assert.Equal(13, pdbReader.Documents.Count); } } }
partial void TryOpenEmbeddedPortablePdb(DebugDirectoryEntry embeddedPdbEntry, ref bool openedEmbeddedPdb, ref MetadataReaderProvider provider, ref Exception errorToReport) { provider = null; MetadataReaderProvider candidate = null; try { candidate = ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdbEntry); // throws if headers are invalid: candidate.GetMetadataReader(); provider = candidate; openedEmbeddedPdb = true; return; } catch (Exception e) when(e is BadImageFormatException || e is IOException) { errorToReport = errorToReport ?? e; openedEmbeddedPdb = false; } finally { if (candidate == null) { candidate?.Dispose(); } } }
/// <summary> /// Unpacks all files stored in a PortablePDB meta-data. The key in the dictionary is the location of a source file /// on the build machine. The value is the content of the source file itself. /// The function will throw an exception if PortablePDB file is not found or anything else went wrong. /// </summary> /// <param name="pdbFilePath">Path to PortablePDB file to load source files from.</param> public static Dictionary <string, CompressedSourceFile> GetEmbeddedFiles(string pdbFilePath) { Dictionary <string, CompressedSourceFile> embeddedFiles = new Dictionary <string, CompressedSourceFile>(); using (FileStream stream = File.OpenRead(pdbFilePath)) using (MetadataReaderProvider metadataReaderProvider = MetadataReaderProvider.FromPortablePdbStream(stream)) { MetadataReader metadataReader = metadataReaderProvider.GetMetadataReader(); CustomDebugInformationHandleCollection customDebugInformationHandles = metadataReader.CustomDebugInformation; foreach (var customDebugInformationHandle in customDebugInformationHandles) { CustomDebugInformation customDebugInformation = metadataReader.GetCustomDebugInformation(customDebugInformationHandle); if (metadataReader.GetGuid(customDebugInformation.Kind) == EmbeddedSource) { byte[] embeddedSource = metadataReader.GetBlobBytes(customDebugInformation.Value); Int32 uncompressedSourceFileSize = BitConverter.ToInt32(embeddedSource, 0); if (uncompressedSourceFileSize != 0) { Document document = metadataReader.GetDocument((DocumentHandle)customDebugInformation.Parent); string sourceFileName = System.IO.Path.GetFullPath(metadataReader.GetString(document.Name)); embeddedFiles.Add(sourceFileName, new CompressedSourceFile(embeddedSource)); } } } } return(embeddedFiles); }
public override IEnumerable <SymbolStoreKey> GetKeys(KeyTypeFlags flags) { if ((flags & KeyTypeFlags.IdentityKey) != 0) { SymbolStoreKey key = null; try { _file.Stream.Position = 0; using (MetadataReaderProvider provider = MetadataReaderProvider.FromPortablePdbStream(_file.Stream, MetadataStreamOptions.LeaveOpen)) { MetadataReader reader = provider.GetMetadataReader(); var blob = new BlobContentId(reader.DebugMetadataHeader.Id); if ((flags & KeyTypeFlags.ForceWindowsPdbs) == 0) { key = GetKey(_file.FileName, blob.Guid); } else { // Force the Windows PDB index key = PDBFileKeyGenerator.GetKey(_file.FileName, blob.Guid, 1); } } } catch (BadImageFormatException ex) { Tracer.Warning("PortablePDBFileKeyGenerator {0}", ex.Message); } if (key != null) { yield return(key); } } }
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); }
private static OpenedReader TryOpenReaderFromCodeView(PEReader peReader, DebugDirectoryEntry codeViewEntry, string assemblyPath) { OpenedReader result = null; MetadataReaderProvider provider = null; try { CodeViewDebugDirectoryData data = peReader.ReadCodeViewDebugDirectoryData(codeViewEntry); string pdbPath = data.Path; Stream pdbStream = null; if (assemblyPath != null) { try { pdbPath = Path.Combine(Path.GetDirectoryName(assemblyPath), GetFileName(pdbPath)); } catch { // invalid characters in CodeView path return(null); } pdbStream = TryOpenFile(pdbPath); } if (pdbStream == null) { if (s_symbolStore == null) { return(null); } Debug.Assert(codeViewEntry.MinorVersion == ImageDebugDirectory.PortablePDBMinorVersion); SymbolStoreKey key = PortablePDBFileKeyGenerator.GetKey(pdbPath, data.Guid); pdbStream = GetSymbolStoreFile(key)?.Stream; } provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream); MetadataReader reader = provider.GetMetadataReader(); // Validate that the PDB matches the assembly version if (data.Age == 1 && new BlobContentId(reader.DebugMetadataHeader.Id) == new BlobContentId(data.Guid, codeViewEntry.Stamp)) { result = new OpenedReader(provider, reader); } } catch (Exception e) when(e is BadImageFormatException || e is IOException) { return(null); } finally { if (result == null) { provider?.Dispose(); } } return(result); }
public DocumentDebugInfoReader(PEReader peReader, MetadataReaderProvider pdbReaderProvider) { _peReader = peReader; _pdbReaderProvider = pdbReaderProvider; _dllReader = _peReader.GetMetadataReader(); _pdbReader = _pdbReaderProvider.GetMetadataReader(); }
private static bool TryMapPortablePdb(Module module, out MetadataReaderProvider metadataReaderProvider) { metadataReaderProvider = null; MetadataReader rd = null; try { metadataReaderProvider = GetMetadataReaderProvider(module); rd = metadataReaderProvider?.GetMetadataReader(); } catch (BadImageFormatException ex) when(ex.Message == "Invalid COR20 header signature.") { TraceSourceLink("no portable PDB found: " + module.FullyQualifiedName); // todo figure out a better way to detect if PDB is portable or classic // https://github.com/dotnet/corefx/blob/06b1365d9881ed26a921490d7edd2d4e4de35565/src/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs#L185 } if (rd == null) { metadataReaderProvider?.Dispose(); metadataReaderProvider = null; return(false); } TraceSourceLink("found portable PDB for: " + module.FullyQualifiedName); // https://github.com/dotnet/symreader-portable/blob/d27c08d6015c4716ced790e34233c0219773ab10/src/Microsoft.DiaSymReader.PortablePdb/Utilities/MetadataUtilities.cs var sourceLinkHandles = rd .GetCustomDebugInformation(EntityHandle.ModuleDefinition) .Where(r => !r.IsNil) .Select(rd.GetCustomDebugInformation) .Where(cdi => !cdi.Value.IsNil && rd.GetGuid(cdi.Kind) == SourceLinkId) .ToList(); if (sourceLinkHandles.Count == 0) { metadataReaderProvider?.Dispose(); metadataReaderProvider = null; return(false); } var sourceLinkHandle = sourceLinkHandles.First(); var sourceLink = SourceLink.Deserialize(rd.GetBlobBytes(sourceLinkHandle.Value)); var hinstance = (long)Marshal.GetHINSTANCE(module); foreach (var dh in rd.Documents) { if (dh.IsNil) { continue; } var doc = rd.GetDocument(dh); var file = rd.GetString(doc.Name); SourceMappedPaths[Tuple.Create(hinstance, file)] = sourceLink.GetUrl(file); } return(true); }
public AssemblyDebugParser(MetadataReaderProvider readerProvider, PdbType pdbType) { _readerProvider = readerProvider; _pdbType = pdbType; // Possible BadImageFormatException if a full PDB is passed // in. We'll let the throw bubble up to something that can handle it _reader = _readerProvider.GetMetadataReader(); }
public PdbDebugInfoProvider(Stream symbolStream) { if (symbolStream is null) { throw new ArgumentNullException(nameof(symbolStream)); } this._readerProvider = MetadataReaderProvider.FromPortablePdbStream(symbolStream); this._reader = _readerProvider.GetMetadataReader(); }
private bool TryOpenPortablePdbFile(string path, BlobContentId id, Func <string, Stream> pdbFileStreamProvider, out MetadataReaderProvider provider, ref Exception errorToReport) { provider = null; MetadataReaderProvider candidate = null; try { Stream pdbStream; try { pdbStream = pdbFileStreamProvider(path); } catch (FileNotFoundException) { // Not an unexpected IO exception, continue witout reporting the error. pdbStream = null; } if (pdbStream == null) { return(false); } if (!pdbStream.CanRead || !pdbStream.CanSeek) { throw new InvalidOperationException("StreamMustSupportReadAndSeek"); } candidate = MetadataReaderProvider.FromPortablePdbStream(pdbStream); // Validate that the PDB matches the assembly version if (new BlobContentId(candidate.GetMetadataReader().DebugMetadataHeader.Id) != id) { return(false); } provider = candidate; return(true); } catch (Exception e) when(e is BadImageFormatException || e is IOException) { errorToReport = errorToReport ?? e; return(false); } finally { if (provider == null) { candidate?.Dispose(); } } }
private static OpenedReader TryOpenReaderFromCodeView(PEReader peReader, DebugDirectoryEntry codeViewEntry, string assemblyPath) { OpenedReader result = null; MetadataReaderProvider provider = null; try { var data = peReader.ReadCodeViewDebugDirectoryData(codeViewEntry); string pdbPath = data.Path; if (assemblyPath != null) { try { pdbPath = Path.Combine(Path.GetDirectoryName(assemblyPath), Path.GetFileName(pdbPath)); } catch { // invalid characters in CodeView path return(null); } } var pdbStream = TryOpenFile(pdbPath); if (pdbStream == null) { return(null); } provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream); var reader = provider.GetMetadataReader(); // Validate that the PDB matches the assembly version if (data.Age == 1 && new BlobContentId(reader.DebugMetadataHeader.Id) == new BlobContentId(data.Guid, codeViewEntry.Stamp)) { result = new OpenedReader(provider, reader); } } catch (Exception e) when(e is BadImageFormatException || e is IOException) { return(null); } finally { if (result == null) { provider?.Dispose(); } } return(result); }
/// <summary> /// Returns the portable PDB reader for the portable PDB stream /// </summary> /// <param name="pdbStream">portable PDB memory or file stream</param> /// <returns>symbol file or null</returns> /// <remarks> /// Assumes that the PDB loaded into memory can be unloaded or moved around. /// </remarks> public ISymbolFile OpenSymbolFile(Stream pdbStream) { if (pdbStream != null) { throw new ArgumentNullException(nameof(pdbStream)); } if (!pdbStream.CanSeek) { throw new ArgumentException(nameof(pdbStream)); } byte[] buffer = new byte[sizeof(uint)]; pdbStream.Position = 0; if (pdbStream.Read(buffer, 0, sizeof(uint)) != sizeof(uint)) { return(null); } uint signature = BitConverter.ToUInt32(buffer, 0); // quick check to avoid throwing exceptions below in common cases: const uint ManagedMetadataSignature = 0x424A5342; if (signature != ManagedMetadataSignature) { // not a Portable PDB return(null); } SymbolFile result = null; MetadataReaderProvider provider = null; try { pdbStream.Position = 0; provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream); result = new SymbolFile(provider, provider.GetMetadataReader()); } catch (Exception e) when(e is BadImageFormatException || e is IOException) { return(null); } finally { if (result == null) { provider?.Dispose(); } } return(result); }
public AssemblyDebugParser(MetadataReaderProvider readerProvider, PdbType pdbType) { _readerProvider = readerProvider; _pdbType = pdbType; try { _reader = _readerProvider.GetMetadataReader(); } catch (BadImageFormatException) // A Full PDB { _pdbType = PdbType.Full; } }
/// <summary> /// Initializes a new instance of the <see cref="PdbFile"/> class. /// </summary> /// <param name="file">File loaded into memory for faster parsing.</param> public unsafe EmbeddedPdbFile(MemoryLoadedFile file) { PEReader peReader = new PEReader(file.BasePointer, (int)file.Length); var debugEntries = peReader.ReadDebugDirectory(); var embeddedPdbEntry = debugEntries.FirstOrDefault(e => e.Type == DebugDirectoryEntryType.EmbeddedPortablePdb); if (embeddedPdbEntry.DataSize == 0) { throw new Exception("PDB wasn't embedded"); } embeddedPdbReaderProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdbEntry); PdbFile = new PdbFile(embeddedPdbReaderProvider.GetMetadataReader()); this.file = file; }
//<SnippetReadSourceLineData> public static void ReadSourceLineData(string pdbPath, int methodToken) { // Determine method row number EntityHandle ehMethod = MetadataTokens.EntityHandle(methodToken); if (ehMethod.Kind != HandleKind.MethodDefinition) { Console.WriteLine($"Invalid token kind: {ehMethod.Kind}"); return; } int rowNumber = MetadataTokens.GetRowNumber(ehMethod); // MethodDebugInformation table is indexed by same row numbers as MethodDefinition table MethodDebugInformationHandle hDebug = MetadataTokens.MethodDebugInformationHandle(rowNumber); // Open Portable PDB file using var fs = new FileStream(pdbPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using MetadataReaderProvider provider = MetadataReaderProvider.FromPortablePdbStream(fs); MetadataReader reader = provider.GetMetadataReader(); if (rowNumber > reader.MethodDebugInformation.Count) { Console.WriteLine("Error: Method row number is out of range"); return; } // Print source line information as console table MethodDebugInformation di = reader.GetMethodDebugInformation(hDebug); Console.WriteLine("IL offset | Start line | Start col. | End line | End col. |"); foreach (SequencePoint sp in di.GetSequencePoints()) { if (sp.IsHidden) { Console.WriteLine($"{sp.Offset.ToString().PadLeft(9)} | (hidden sequence point)"); } else { Console.WriteLine("{0} |{1} |{2} |{3} |{4} |", sp.Offset.ToString().PadLeft(9), sp.StartLine.ToString().PadLeft(11), sp.StartColumn.ToString().PadLeft(11), sp.EndLine.ToString().PadLeft(9), sp.EndColumn.ToString().PadLeft(9)); } } }
private void ValidateEmbeddedPortablePdb(PEReader reader) { var entries = reader.ReadDebugDirectory(); Assert.Equal(DebugDirectoryEntryType.CodeView, entries[0].Type); Assert.Equal(DebugDirectoryEntryType.Reproducible, entries[1].Type); Assert.Equal(DebugDirectoryEntryType.EmbeddedPortablePdb, entries[2].Type); using (MetadataReaderProvider provider = reader.ReadEmbeddedPortablePdbDebugDirectoryData(entries[2])) { var pdbReader = provider.GetMetadataReader(); var document = pdbReader.GetDocument(pdbReader.Documents.First()); Assert.Equal(@"C:\Documents.cs", pdbReader.GetString(document.Name)); } }
public static PdbSymbolReader TryOpenEmbedded(PEReader peReader, MetadataStringDecoder stringDecoder) { foreach (DebugDirectoryEntry debugEntry in peReader.ReadDebugDirectory()) { if (debugEntry.Type != DebugDirectoryEntryType.EmbeddedPortablePdb) { continue; } MetadataReaderProvider embeddedReaderProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(debugEntry); MetadataReader reader = embeddedReaderProvider.GetMetadataReader(MetadataReaderOptions.Default, stringDecoder); return(new PortablePdbSymbolReader(reader, mappedViewAccessor: null)); } return(null); }
public override bool IsValid() { try { _file.Stream.Position = 0; using (MetadataReaderProvider provider = MetadataReaderProvider.FromPortablePdbStream(_file.Stream, MetadataStreamOptions.LeaveOpen)) { MetadataReader reader = provider.GetMetadataReader(); return(true); } } catch (BadImageFormatException) { } return(false); }
internal MetadataReader?GetMetadataReader() { try { hasError = false; return(provider.GetMetadataReader()); } catch (BadImageFormatException) { hasError = true; return(null); } catch (IOException) { hasError = true; return(null); } }
public bool PortablePdbHasLocalSource(string module, out string firstNotFoundDocument) { firstNotFoundDocument = ""; using (var moduleStream = _fileSystem.OpenRead(module)) using (var peReader = new PEReader(moduleStream)) { foreach (var entry in peReader.ReadDebugDirectory()) { if (entry.Type == DebugDirectoryEntryType.CodeView) { var codeViewData = peReader.ReadCodeViewDebugDirectoryData(entry); using Stream pdbStream = _fileSystem.OpenRead(_sourceRootTranslator.ResolveFilePath(codeViewData.Path)); using MetadataReaderProvider metadataReaderProvider = MetadataReaderProvider.FromPortablePdbStream(pdbStream); MetadataReader metadataReader = null; try { metadataReader = metadataReaderProvider.GetMetadataReader(); } catch (BadImageFormatException) { _logger.LogWarning($"{nameof(BadImageFormatException)} during MetadataReaderProvider.FromPortablePdbStream in InstrumentationHelper.PortablePdbHasLocalSource, unable to check if module has got local source."); return(true); } foreach (DocumentHandle docHandle in metadataReader.Documents) { Document document = metadataReader.GetDocument(docHandle); string docName = _sourceRootTranslator.ResolveFilePath(metadataReader.GetString(document.Name)); // We verify all docs and return false if not all are present in local // We could have false negative if doc is not a source // Btw check for all possible extension could be weak approach // We exlude from the check the autogenerated source file(i.e. source generators) if (!_fileSystem.Exists(docName) && !docName.EndsWith(".g.cs")) { firstNotFoundDocument = docName; return(false); } } } } } return(true); }
private unsafe void TestGetMetadataReader(MetadataReaderProvider provider) { var decoder = new TestMetadataStringDecoder(Encoding.UTF8, (a, b) => "str"); var reader1 = provider.GetMetadataReader(MetadataReaderOptions.None, decoder); Assert.Equal("str", reader1.MetadataVersion); Assert.Same(reader1.Utf8Decoder, decoder); Assert.Equal(reader1.Options, MetadataReaderOptions.None); var reader2 = provider.GetMetadataReader(MetadataReaderOptions.None, decoder); Assert.Same(reader1, reader2); var reader3 = provider.GetMetadataReader(MetadataReaderOptions.None); Assert.NotSame(reader2, reader3); Assert.Equal("v9.9.9.9", reader3.MetadataVersion); Assert.Same(reader3.Utf8Decoder, MetadataStringDecoder.DefaultUTF8); Assert.Equal(reader3.Options, MetadataReaderOptions.None); var reader4 = provider.GetMetadataReader(MetadataReaderOptions.None); Assert.Same(reader3, reader4); var reader5 = provider.GetMetadataReader(MetadataReaderOptions.ApplyWindowsRuntimeProjections); Assert.NotSame(reader4, reader5); Assert.Equal("v9.9.9.9", reader5.MetadataVersion); Assert.Same(reader5.Utf8Decoder, MetadataStringDecoder.DefaultUTF8); Assert.Equal(reader5.Options, MetadataReaderOptions.ApplyWindowsRuntimeProjections); provider.Dispose(); Assert.Throws<ObjectDisposedException>(() => provider.GetMetadataReader(MetadataReaderOptions.ApplyWindowsRuntimeProjections)); Assert.Throws<ObjectDisposedException>(() => provider.GetMetadataReader()); }