private SymbolFile TryOpenReaderFromEmbeddedPdb(PEReader peReader, DebugDirectoryEntry embeddedPdbEntry) { SymbolFile 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 SymbolFile(provider, provider.GetMetadataReader()); } 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); }
private SymbolFile TryOpenReaderFromCodeView(PEReader peReader, DebugDirectoryEntry codeViewEntry, string assemblyPath) { SymbolFile 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 = Utilities.TryOpenFile(pdbPath); } if (pdbStream == null) { if (IsSymbolStoreEnabled) { Debug.Assert(codeViewEntry.MinorVersion == ImageDebugDirectory.PortablePDBMinorVersion); SymbolStoreKey key = PortablePDBFileKeyGenerator.GetKey(pdbPath, data.Guid); pdbStream = GetSymbolStoreFile(key)?.Stream; } if (pdbStream == null) { return(null); } // Make sure the stream is at the beginning of the pdb. pdbStream.Position = 0; } 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 SymbolFile(provider, reader); } } catch (Exception e) when(e is BadImageFormatException || e is IOException) { return(null); } finally { if (result == null) { provider?.Dispose(); } } return(result); }