Exemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PortablePdbReader"/> class.
        /// </summary>
        /// <param name="stream">
        /// Portable pdb stream
        /// </param>
        /// <exception cref="Exception">
        /// Raises Exception on given stream is not portable pdb stream
        /// </exception>
        public PortablePdbReader(Stream stream)
        {
            if (!IsPortable(stream))
            {
                throw new Exception("Given stream is not portable stream");
            }

            this.provider = MetadataReaderProvider.FromPortablePdbStream(stream);
            this.reader   = this.provider.GetMetadataReader();
        }
Exemplo n.º 2
0
        public void TestTypetoDocumentNavigationMethod()
        {
            string sourceA = @"
using System;

public class C
{
    public void F2() { }
}
";

            string sourceB = @"
using System;

public class D
{
   
       
}
";

            var c1 = CreateCompilation(new[]
            {
                SyntaxFactory.ParseSyntaxTree(sourceA, path: "X.cs", encoding: Encoding.UTF8),
                SyntaxFactory.ParseSyntaxTree(sourceB, path: "Z.cs", encoding: Encoding.UTF8)
            }, options: TestOptions.DebugDll);

            var pdbStream = new MemoryStream();
            var peImage   = c1.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb), pdbStream: pdbStream);

            pdbStream.Position = 0;


            string source2           = @"
using System;

public class Program
{
    public static void Main() { }   
}
";
            var    assemblyMetadata  = AssemblyMetadata.CreateFromImage(peImage);
            var    metadataReference = assemblyMetadata.GetReference();
            var    c2 = CreateCompilation(new[] { source2 }, new[] { metadataReference }, options: TestOptions.DebugDll);

            var    typeC  = c2.GetTypeByMetadataName("C");
            Symbol symbol = typeC.GetMethod("F2");

            //symbol = (PEMethodSymbol)symbol;
            using var provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
            var pdbReader = provider.GetMetadataReader();
            var docList   = FindSourceDocuments(symbol, pdbReader);

            Assert.Equal(0x30000001, MetadataTokens.GetToken(docList[0]));
        }
Exemplo n.º 3
0
        public void SourceLink()
        {
            string source =
                @"
using System;

class C
{
    public static void Main()
    {
        Console.WriteLine();
    }
}
";
            var sourceLinkBlob = Encoding.UTF8.GetBytes(
                @"
{
  ""documents"": {
     ""f:/build/*"" : ""https://raw.githubusercontent.com/my-org/my-project/1111111111111111111111111111111111111111/*""
  }
}
"
                );

            var c = CreateCompilation(
                Parse(source, "f:/build/goo.cs"),
                options: TestOptions.DebugDll
                );

            var pdbStream = new MemoryStream();

            c.EmitToArray(
                EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb),
                pdbStream: pdbStream,
                sourceLinkStream: new MemoryStream(sourceLinkBlob)
                );
            pdbStream.Position = 0;

            using (var provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream))
            {
                var pdbReader = provider.GetMetadataReader();

                var actualBlob = (
                    from cdiHandle in pdbReader.GetCustomDebugInformation(
                        EntityHandle.ModuleDefinition
                        )
                    let cdi = pdbReader.GetCustomDebugInformation(cdiHandle)
                              where pdbReader.GetGuid(cdi.Kind) == PortableCustomDebugInfoKinds.SourceLink
                              select pdbReader.GetBlobBytes(cdi.Value)
                    ).Single();

                AssertEx.Equal(sourceLinkBlob, actualBlob);
            }
        }
Exemplo n.º 4
0
        public MetadataReader GetMetadataReaderfromSource(string source)
        {
            var c         = CreateCompilation(new[] { source }, options: TestOptions.DebugDll);
            var pdbStream = new MemoryStream();
            var peImage   = c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb), pdbStream: pdbStream);

            pdbStream.Position = 0;
            var provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);

            return(provider.GetMetadataReader());
        }
Exemplo n.º 5
0
        public bool EnC(byte[] meta, byte[] pdb)
        {
            var            asmStream         = new MemoryStream(meta);
            MetadataReader asmMetadataReader = MetadataReaderProvider.FromMetadataStream(asmStream).GetMetadataReader();
            var            pdbStream         = new MemoryStream(pdb);
            MetadataReader pdbMetadataReader = MetadataReaderProvider.FromPortablePdbStream(pdbStream).GetMetadataReader();

            enCMetadataReader.Add(asmMetadataReader);
            enCMetadataReader.Add(pdbMetadataReader);
            PopulateEnC(asmMetadataReader, pdbMetadataReader);
            return(true);
        }
Exemplo n.º 6
0
        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(SR.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();
                }
            }
        }
        public void AddPdb(Stream peStream, Stream pdbStream)
        {
            using (var peReader = new PEReader(peStream))
                using (var pdbProvider = MetadataReaderProvider.FromPortablePdbStream(pdbStream))
                {
                    var peMetadataReader  = peReader.GetMetadataReader();
                    var pdbMetadataReader = pdbProvider.GetMetadataReader();
                    var moduleName        = peMetadataReader.GetString(peMetadataReader.GetModuleDefinition().Name);

                    AddPdb(moduleName, peMetadataReader, pdbMetadataReader);
                }
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        public MetadataReader GetMetadataReaderfromTwoSource(string source, string sourceB)
        {
            var sourceTreeA = SyntaxFactory.ParseSyntaxTree(source, path: "a.cs", encoding: Encoding.UTF8);
            var sourceTreeB = SyntaxFactory.ParseSyntaxTree(sourceB, path: "b.cs", encoding: Encoding.UTF8);
            var c           = CreateCompilation(new[] { sourceTreeA, sourceTreeB }, options: TestOptions.DebugDll);
            var pdbStream   = new MemoryStream();
            var peImage     = c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb), pdbStream: pdbStream);

            pdbStream.Position = 0;
            var provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);

            return(provider.GetMetadataReader());
        }
Exemplo n.º 10
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);
        }
        public AssemblyDebugParser(Stream?peStream, Stream pdbStream)
        {
            Stream inputStream;

            if (!PdbConverter.IsPortable(pdbStream))
            {
                if (peStream == null)
                {
                    throw new ArgumentNullException(nameof(peStream), "Full PDB's require the PE file to be next to the PDB");
                }

                if (!AppCompat.IsSupported(RuntimeFeature.DiaSymReader))
                {
                    throw new PlatformNotSupportedException("Windows PDB cannot be processed on this platform.");
                }

                // Full PDB. convert to ppdb in memory

                _pdbBytes          = pdbStream.ReadAllBytes();
                pdbStream.Position = 0;
                _peBytes           = peStream.ReadAllBytes();
                peStream.Position  = 0;

                _temporaryPdbStream = new MemoryStream();
                PdbConverter.Default.ConvertWindowsToPortable(peStream, pdbStream, _temporaryPdbStream);
                _temporaryPdbStream.Position = 0;
                peStream.Position            = 0;
                inputStream = _temporaryPdbStream;
                _pdbType    = PdbType.Full;
            }
            else
            {
                inputStream        = pdbStream;
                _pdbType           = PdbType.Portable;
                _pdbBytes          = pdbStream.ReadAllBytes();
                pdbStream.Position = 0;
            }



            _readerProvider = MetadataReaderProvider.FromPortablePdbStream(inputStream);
            _reader         = _readerProvider.GetMetadataReader();

            if (peStream != null)
            {
                _peReader    = new PEReader(peStream);
                _ownPeReader = true;
            }
        }
Exemplo n.º 12
0
        //<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 bool HasSourceLinkDebugInformation(Stream pdbStream)
        {
            if (!pdbStream.CanSeek)
            {
                using var seekablePdbStream = new MemoryStream();
                pdbStream.CopyTo(seekablePdbStream);
                seekablePdbStream.Position = 0;

                return(HasSourceLinkDebugInformation(seekablePdbStream));
            }

            using var pdbReaderProvider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
            var pdbReader = pdbReaderProvider.GetMetadataReader();

            return(HasSourceLinkDebugInformation(pdbReader));
        }
Exemplo n.º 14
0
 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);
 }
Exemplo n.º 15
0
        public void EndToEnd_WindowsToPortable_ImplicitPath()
        {
            var dir = _temp.CreateDirectory();
            var pe  = dir.CreateFile("SourceData.dll").WriteAllBytes(TestResources.SourceData.WindowsDll);

            dir.CreateFile("SourceData.pdb").WriteAllBytes(TestResources.SourceData.WindowsPdb);
            var outPdb = dir.CreateFile("SourceLink.pdb").WriteAllText("dummy");

            Assert.True(Pdb2Pdb.Convert(new Pdb2Pdb.Args(
                                            peFilePath: pe.Path,
                                            pdbFilePathOpt: null,
                                            outPdbFilePathOpt: outPdb.Path,
                                            options: PortablePdbConversionOptions.Default,
                                            suppressedWarnings: ImmutableArray <PdbDiagnosticId> .Empty,
                                            suppressAllWarnings: false,
                                            extract: false)));

            using (var provider = MetadataReaderProvider.FromPortablePdbStream(File.OpenRead(outPdb.Path)))
            {
                var sourceLinkCdiGuid = new Guid("CC110556-A091-4D38-9FEC-25AB9A351A6A");

                var mdReader   = provider.GetMetadataReader();
                var sourceLink = from cdiHandle in mdReader.CustomDebugInformation
                                 let cdi = mdReader.GetCustomDebugInformation(cdiHandle)
                                           where mdReader.GetGuid(cdi.Kind) == sourceLinkCdiGuid
                                           select Encoding.UTF8.GetString(mdReader.GetBlobBytes(cdi.Value));

                AssertEx.AssertLinesEqual(@"
{
""documents"": {
    ""C:\Documents.cs"": ""http://server/3/Documents.cs.g"",
    ""C:\a\b\c\d\1.cs"": ""http://server/1/a/b/c/d/1.cs"",
    ""C:\a\b\c\D\2.cs"": ""http://server/1/a/b/c/D/2.cs"",
    ""C:\a\b\C\d\3.cs"": ""http://server/1/a/b/C/d/3.cs"",
    ""C:\a\b\c\d\x.cs"": ""http://server/1/a/b/c/d/x.cs"",
    ""C:\A\b\c\x.cs"": ""http://server/1/a/b/c/x.cs"",
    ""C:\a\b\x.cs"": ""http://server/1/a/b/x.cs"",
    ""C:\a\B\3.cs"": ""http://server/1/a/B/3.cs"",
    ""C:\a\B\c\4.cs"": ""http://server/1/a/B/c/4.cs"",
    "":6.cs"": ""http://server/4/%3A6.cs"",
    ""C:\a\b\X.cs"": ""http://server/1/a/b/X.cs"",
    ""C:\a\B\x.cs"": ""http://server/1/a/B/x.cs""
  }
}
", sourceLink.Single());
            }
        }
Exemplo n.º 16
0
        private MetadataReader GetMetadataReader(string assemblyPath)
        {
            if (!_cache.TryGetValue(assemblyPath, out var provider))
            {
                var pdbPath = GetPdbPath(assemblyPath);

                if (!string.IsNullOrEmpty(pdbPath) && File.Exists(pdbPath) && IsPortable(pdbPath))
                {
                    var pdbStream = File.OpenRead(pdbPath);
                    provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
                }

                _cache[assemblyPath] = provider;
            }

            return(provider?.GetMetadataReader());
        }
Exemplo n.º 17
0
        /// <summary>
        /// The output file format looks something like this
        /// "Module.dll\0Namspace.SubNamespace\0Class\0Method\0"
        /// + 32-bit big-endian sequence point count
        /// + (32-bit big-endian sequence point offset) * sequence point count
        /// </summary>
        public static void WriteSequencePointsToFile(Stream peStream, Stream pdbStream, Stream outputFile)
        {
            var peReader          = new PEReader(peStream);
            var pdbProvider       = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
            var peMetadataReader  = peReader.GetMetadataReader();
            var pdbMetadataReader = pdbProvider.GetMetadataReader();

            var moduleNameBytes = Encoding.UTF8.GetBytes(peMetadataReader.GetString(peMetadataReader.GetModuleDefinition().Name));

            foreach (var methodDebugInfoHandle in pdbMetadataReader.MethodDebugInformation)
            {
                var methodDebugInfo      = pdbMetadataReader.GetMethodDebugInformation(methodDebugInfoHandle);
                var methodDefHandle      = methodDebugInfoHandle.ToDefinitionHandle();
                var methodDef            = peMetadataReader.GetMethodDefinition(methodDefHandle);
                var document             = pdbMetadataReader.GetDocument(methodDebugInfo.Document);
                var methodDefToken       = MetadataTokens.GetToken(methodDefHandle);
                var methodDebugInfoToken = MetadataTokens.GetToken(methodDefHandle);
                var declaringType        = peMetadataReader.GetTypeDefinition(methodDef.GetDeclaringType());

                var namespaceNameBytes = Encoding.UTF8.GetBytes(peMetadataReader.GetString(declaringType.Namespace));
                var classNameBytes     = Encoding.UTF8.GetBytes(peMetadataReader.GetString(declaringType.Name));
                var methodNameBytes    = Encoding.UTF8.GetBytes(peMetadataReader.GetString(methodDef.Name));

                var sequencePoints = methodDebugInfo.GetSequencePoints().Where(sp => !sp.IsHidden).ToArray();

                outputFile.Write(moduleNameBytes, 0, moduleNameBytes.Length);
                outputFile.WriteByte(0);
                outputFile.Write(namespaceNameBytes, 0, namespaceNameBytes.Length);
                outputFile.WriteByte(0);
                outputFile.Write(classNameBytes, 0, classNameBytes.Length);
                outputFile.WriteByte(0);
                outputFile.Write(methodNameBytes, 0, methodNameBytes.Length);
                outputFile.WriteByte(0);
                WriteInt32(outputFile, sequencePoints.Length);

                foreach (var sequencePoint in sequencePoints)
                {
                    WriteInt32(outputFile, sequencePoint.Offset);
                    //Console.WriteLine($"document name: {pdbMetadataReader.GetString(document.Name)} namespace: {peMetadataReader.GetString(declaringType.Namespace)} class name: {peMetadataReader.GetString(declaringType.Name)} method name: {peMetadataReader.GetString(methodDef.Name)} method def token: {methodDefToken} method debug info token: {methodDebugInfoToken} start line: {sequencePoint.StartLine} offset: {sequencePoint.Offset}");
                }
            }

            outputFile.WriteByte(0);
        }
Exemplo n.º 18
0
        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.NewFileStream(codeViewData.Path, FileMode.Open);
                            using MetadataReaderProvider metadataReaderProvider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
                            MetadataReader metadataReader = null;
                            try
                            {
                                metadataReader = metadataReaderProvider.GetMetadataReader();
                            }
                            catch (BadImageFormatException)
                            {
                                // TODO log this to warning
                                // In case of non portable pdb we get exception so we skip file sources check
                                return(true);
                            }
                            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);
        }
        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);
        }
Exemplo n.º 20
0
        public unsafe AssemblyInfo(MonoProxy monoProxy, SessionId sessionId, string url, byte[] assembly, byte[] pdb, CancellationToken token)
        {
            debugId             = -1;
            this.id             = Interlocked.Increment(ref next_id);
            using var asmStream = new MemoryStream(assembly);
            peReader            = new PEReader(asmStream);
            var entries = peReader.ReadDebugDirectory();

            if (entries.Length > 0)
            {
                var codeView = entries[0];
                CodeViewDebugDirectoryData codeViewData = peReader.ReadCodeViewDebugDirectoryData(codeView);
                PdbAge  = codeViewData.Age;
                PdbGuid = codeViewData.Guid;
                PdbName = codeViewData.Path;
                PdbInformationAvailable = true;
            }
            asmMetadataReader = PEReaderExtensions.GetMetadataReader(peReader);
            var asmDef = asmMetadataReader.GetAssemblyDefinition();

            Name = asmDef.GetAssemblyName().Name + ".dll";
            if (pdb != null)
            {
                var pdbStream = new MemoryStream(pdb);
                try
                {
                    // MetadataReaderProvider.FromPortablePdbStream takes ownership of the stream
                    pdbMetadataReader = MetadataReaderProvider.FromPortablePdbStream(pdbStream).GetMetadataReader();
                }
                catch (BadImageFormatException)
                {
                    monoProxy.SendLog(sessionId, $"Warning: Unable to read debug information of: {Name} (use DebugType=Portable/Embedded)", token);
                }
            }
            else
            {
                var embeddedPdbEntry = entries.FirstOrDefault(e => e.Type == DebugDirectoryEntryType.EmbeddedPortablePdb);
                if (embeddedPdbEntry.DataSize != 0)
                {
                    pdbMetadataReader = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdbEntry).GetMetadataReader();
                }
            }
            Populate();
        }
Exemplo n.º 21
0
        /// <summary>
        /// Returns metadata readers for assembly PE file and portable PDB.
        /// </summary>
        /// <param name="assemblyFileName">file name of the assembly</param>
        /// <param name="peReader">PE metadata reader return</param>
        /// <param name="pdbReader">PDB metadata reader return</param>
        /// <returns>true if debugging information is available</returns>
        private static bool GetReaders(string assemblyFileName, out MetadataReader peReader, out MetadataReader pdbReader)
        {
            peReader  = null;
            pdbReader = null;

            if (!File.Exists(assemblyFileName))
            {
                return(false);
            }
            Stream   peStream = File.OpenRead(assemblyFileName);
            PEReader reader   = new PEReader(peStream);
            string   pdbPath  = null;

            foreach (DebugDirectoryEntry entry in reader.ReadDebugDirectory())
            {
                if (entry.Type == DebugDirectoryEntryType.CodeView)
                {
                    CodeViewDebugDirectoryData codeViewData = reader.ReadCodeViewDebugDirectoryData(entry);
                    pdbPath = codeViewData.Path;
                    break;
                }
            }
            if (pdbPath == null)
            {
                return(false);
            }
            if (!File.Exists(pdbPath))
            {
                pdbPath = Path.GetFileName(pdbPath);
                if (!File.Exists(pdbPath))
                {
                    return(false);
                }
            }

            peReader = reader.GetMetadataReader();
            Stream pdbStream = File.OpenRead(pdbPath);
            MetadataReaderProvider provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream);

            pdbReader = provider.GetMetadataReader();

            return(true);
        }
Exemplo n.º 22
0
        private static OpenedReader TryOpenReaderForInMemoryPdb(Stream pdbStream)
        {
            Debug.Assert(pdbStream != null);

            byte[] buffer = new byte[sizeof(uint)];
            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);
            }

            OpenedReader           result   = null;
            MetadataReaderProvider provider = null;

            try
            {
                pdbStream.Position = 0;
                provider           = MetadataReaderProvider.FromPortablePdbStream(pdbStream);
                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 void VerifyPortablePdb(Stream pdbStream, string expectedMetadata, string message)
        {
            using (var provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream, MetadataStreamOptions.LeaveOpen))
            {
                var mdReader = provider.GetMetadataReader();
                var writer   = new StringWriter();
                var mdv      = new MetadataVisualizer(mdReader, writer, MetadataVisualizerOptions.NoHeapReferences);

                mdv.WriteDocument();
                mdv.WriteMethodDebugInformation();
                mdv.WriteLocalScope();
                mdv.WriteLocalVariable();
                mdv.WriteLocalConstant();
                mdv.WriteImportScope();
                mdv.WriteCustomDebugInformation();

                AssertEx.AssertLinesEqual(expectedMetadata, writer.ToString(), message);
            }
        }
Exemplo n.º 24
0
        private async Task <PortablePdb> ExtractPortablePdbAsync(
            PackageArchiveReader symbolPackage,
            string pdbPath,
            CancellationToken cancellationToken)
        {
            // TODO: Validate that the PDB has a corresponding DLL
            // See: https://github.com/NuGet/NuGet.Jobs/blob/master/src/Validation.Symbols/SymbolsValidatorService.cs#L170
            Stream      pdbStream = null;
            PortablePdb result    = null;

            try
            {
                using (var rawPdbStream = await symbolPackage.GetStreamAsync(pdbPath, cancellationToken))
                {
                    pdbStream = await rawPdbStream.AsTemporaryFileStreamAsync();

                    string signature;
                    using (var pdbReaderProvider = MetadataReaderProvider.FromPortablePdbStream(pdbStream, MetadataStreamOptions.LeaveOpen))
                    {
                        var reader = pdbReaderProvider.GetMetadataReader();
                        var id     = new BlobContentId(reader.DebugMetadataHeader.Id);

                        signature = id.Guid.ToString("N").ToUpperInvariant();
                    }

                    var fileName = Path.GetFileName(pdbPath).ToLowerInvariant();
                    var key      = $"{signature}ffffffff";

                    pdbStream.Position = 0;
                    result             = new PortablePdb(fileName, key, pdbStream);
                }
            }
            finally
            {
                if (result == null)
                {
                    pdbStream?.Dispose();
                }
            }

            return(result);
        }
Exemplo n.º 25
0
        public string GetSourceLinkBlob()
        {
            using (var provider = MetadataReaderProvider.FromPortablePdbStream(GetStream())) {
                var pdbReader = provider.GetMetadataReader();

                var jsonBlob =
                    pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition)
                    .Select(cdiHandle => pdbReader.GetCustomDebugInformation(cdiHandle))
                    .Where(cdi => pdbReader.GetGuid(cdi.Kind) == SourceLinkGuid)
                    .Select(cdi => pdbReader.GetBlobBytes(cdi.Value))
                    .FirstOrDefault();

                if (jsonBlob == null)
                {
                    return(null);
                }

                return(System.Text.Encoding.UTF8.GetString(jsonBlob));
            }
        }
        public AssemblyDebugParser(Stream?peStream, Stream pdbStream)
        {
            Stream inputStream;

            if (!PdbConverter.IsPortable(pdbStream))
            {
                if (peStream == null)
                {
                    throw new ArgumentNullException(nameof(peStream), "Full PDB's require the PE file to be next to the PDB");
                }
                // Full PDB. convert to ppdb in memory

                _pdbBytes          = pdbStream.ReadAllBytes();
                pdbStream.Position = 0;
                _peBytes           = peStream.ReadAllBytes();
                peStream.Position  = 0;

                _temporaryPdbStream = new MemoryStream();
                PdbConverter.Default.ConvertWindowsToPortable(peStream, pdbStream, _temporaryPdbStream);
                _temporaryPdbStream.Position = 0;
                peStream.Position            = 0;
                inputStream = _temporaryPdbStream;
                _pdbType    = PdbType.Full;
            }
            else
            {
                inputStream        = pdbStream;
                _pdbType           = PdbType.Portable;
                _pdbBytes          = pdbStream.ReadAllBytes();
                pdbStream.Position = 0;
            }



            _readerProvider = MetadataReaderProvider.FromPortablePdbStream(inputStream);
            _reader         = _readerProvider.GetMetadataReader();

            _peReader = new PEReader(peStream !);
            //_peReader.
            _ownPeReader = true;
        }
Exemplo n.º 27
0
        public void EmbeddedSource()
        {
            string source = @"
using System;

class C
{
    public static void Main()
    {
        Console.WriteLine();
    }
}
";
            var    tree   = Parse(source, "f:/build/foo.cs");
            var    c      = CreateCompilationWithMscorlib(tree, options: TestOptions.DebugDll);

            var pdbStream = new MemoryStream();

            c.EmitToArray(
                EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb),
                pdbStream: pdbStream,
                embeddedTexts: new[] { EmbeddedText.FromSource(tree.FilePath, tree.GetText()) });
            pdbStream.Position = 0;

            using (var provider = MetadataReaderProvider.FromPortablePdbStream(pdbStream))
            {
                var pdbReader = provider.GetMetadataReader();

                var embeddedSource =
                    (from documentHandle in pdbReader.Documents
                     let document = pdbReader.GetDocument(documentHandle)
                                    select new
                {
                    FilePath = pdbReader.GetString(document.Name),
                    Text = pdbReader.GetEmbeddedSource(documentHandle)
                }).Single();

                Assert.Equal(embeddedSource.FilePath, "f:/build/foo.cs");
                Assert.Equal(source, embeddedSource.Text.ToString());
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// This gets format for the VSTS symbol server indexed files. This format is
        /// based off of the PDB name and the signature present in the PDB
        /// </summary>
        /// <param name="pdbFullPath">Path to the PDB file</param>
        /// <returns>The indexed format of PDB file for the VSTS symbol server</returns>
        public static string GetIndex(string pdbFullPath)
        {
            if (pdbFullPath == null)
            {
                throw new ArgumentNullException(nameof(pdbFullPath));
            }

            var indexingPath = string.Empty;

            using (var stream = File.OpenRead(pdbFullPath))
                using (var pdbReaderProvider = MetadataReaderProvider.FromPortablePdbStream(stream, MetadataStreamOptions.LeaveOpen))
                {
                    var pdbReader    = pdbReaderProvider.GetMetadataReader();
                    var pdbSignature = new BlobContentId(pdbReader.DebugMetadataHeader.Id).Guid;
                    var pdbFileName  = Path.GetFileName(pdbFullPath).ToLowerInvariant();
                    var pdbAge       = "FFFFFFFF";
                    indexingPath = $"{pdbFileName}/{pdbSignature.ToString("N")}{pdbAge}/{pdbFileName}";
                }

            return(indexingPath);
        }
Exemplo n.º 29
0
 internal string [] TupleElementNamesPrivate(MethodMirror method, int localVariableIndex)
 {
     using (var metadataReader = MetadataReaderProvider.FromPortablePdbStream(GetStream())) {
         var reader       = metadataReader.GetMetadataReader();
         var methodHandle = MetadataTokens.MethodDefinitionHandle(method.MetadataToken);
         var localScopes  = reader.GetLocalScopes(methodHandle);
         // localVariableIndex is not really il_index, but sequential index when fetching locals
         // hence use Skip(index) instead of Index matching.
         var localVar         = localScopes.Select(s => reader.GetLocalScope(s)).SelectMany(s => s.GetLocalVariables()).Skip(localVariableIndex).First();
         var customDebugInfos = reader.GetCustomDebugInformation(localVar);
         foreach (var item in customDebugInfos)
         {
             var debugInfo = reader.GetCustomDebugInformation(item);
             if (reader.GetGuid(debugInfo.Kind) == TupleElementNames)
             {
                 return(DecodeTupleElementNames(reader.GetBlobReader(debugInfo.Value)));
             }
         }
     }
     return(null);
 }
Exemplo n.º 30
0
        /// <summary>
        /// Constructs new assembly debug information.
        /// </summary>
        /// <param name="assembly">The referenced assembly.</param>
        /// <param name="pdbStream">The associated PDB stream.</param>
        internal AssemblyDebugInformation(Assembly assembly, Stream pdbStream)
        {
            Assembly = assembly;
            Modules  = ImmutableArray.Create(assembly.GetModules());

            using (var metadataReaderProvider = MetadataReaderProvider.FromPortablePdbStream(pdbStream, 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));
                }
            }
        }