Example #1
0
        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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        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);
        }