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));
 }
Пример #2
0
        /// <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 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);
        }