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));
 }
Ejemplo n.º 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);
        }
Ejemplo n.º 3
0
        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);
        }