private PdbToXmlConverter(XmlWriter writer, ISymUnmanagedReader symReader, MetadataReader metadataReader, PdbToXmlOptions options) { _symReader = symReader; _metadataReader = metadataReader; _writer = writer; _options = options; }
public unsafe static void ToXml(TextWriter xmlWriter, Stream pdbStream, Stream peStream, PdbToXmlOptions options = PdbToXmlOptions.Default, string methodName = null) { IEnumerable<MethodHandle> methodHandles; var headers = new PEHeaders(peStream); byte[] metadata = new byte[headers.MetadataSize]; peStream.Seek(headers.MetadataStartOffset, SeekOrigin.Begin); peStream.Read(metadata, 0, headers.MetadataSize); fixed (byte* metadataPtr = metadata) { var metadataReader = new MetadataReader((IntPtr)metadataPtr, metadata.Length); if (string.IsNullOrEmpty(methodName)) { methodHandles = metadataReader.MethodDefinitions; } else { methodHandles = metadataReader.MethodDefinitions. Where(methodHandle => GetQualifiedMethodName(metadataReader, methodHandle) == methodName); } ToXml(xmlWriter, pdbStream, metadataReader, options, methodHandles); } }
private PdbToXmlConverter(XmlWriter writer, TempPdbReader pdbReader, MetadataReader metadataReader, PdbToXmlOptions options) { this.pdbReader = pdbReader; this.metadataReader = metadataReader; this.writer = writer; this.options = options; }
internal static void VerifyPdb( this Compilation compilation, string expectedPdb, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber]int expectedValueSourceLine = 0, [CallerFilePath]string expectedValueSourcePath = null) { VerifyPdb(compilation, "", expectedPdb, format, options, expectedValueSourceLine, expectedValueSourcePath); }
public CompilationVerifier VerifyPdb( string expectedPdb, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { _compilation.VerifyPdb(expectedPdb, format, options, expectedValueSourceLine, expectedValueSourcePath); return(this); }
internal static void VerifyPdb( this Compilation compilation, string expectedPdb, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { VerifyPdb(compilation, "", expectedPdb, format, options, expectedValueSourceLine, expectedValueSourcePath); }
public static void VerifyPortablePdb( TestResource portable, string expectedXml, PdbToXmlOptions options = Options) { var portablePEStream = new MemoryStream(portable.PE); var portablePdbStream = new MemoryStream(portable.Pdb); var actualXml = PdbToXmlConverter.ToXml(portablePdbStream, portablePEStream, options); AssertEx.AssertLinesEqual(expectedXml, actualXml, "Comparing Portable PDB with expected XML"); }
public CompilationVerifier VerifyPdb( XElement expectedPdb, IMethodSymbol debugEntryPoint = null, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { _compilation.VerifyPdb(expectedPdb, debugEntryPoint, format, options, expectedValueSourceLine, expectedValueSourcePath); return(this); }
internal static void VerifyPdb( this Compilation compilation, XElement expectedPdb, IMethodSymbol debugEntryPoint = null, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { VerifyPdb(compilation, "", expectedPdb, debugEntryPoint, format, options, expectedValueSourceLine, expectedValueSourcePath); }
public static void VerifyPdb( this Compilation compilation, string expectedPdb, IEnumerable <EmbeddedText> embeddedTexts = null, IMethodSymbol debugEntryPoint = null, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { VerifyPdb(compilation, "", expectedPdb, embeddedTexts, debugEntryPoint, format, options, expectedValueSourceLine, expectedValueSourcePath); }
public static CompilationVerifier VerifyPdb( this CompilationVerifier verifier, XElement expectedPdb, IEnumerable <EmbeddedText> embeddedTexts = null, IMethodSymbol debugEntryPoint = null, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { verifier.Compilation.VerifyPdb(expectedPdb, embeddedTexts, debugEntryPoint, format, options, expectedValueSourceLine, expectedValueSourcePath); return(verifier); }
public static void GenXmlFromPdb(string exePath, string pdbPath, string outPath, PdbToXmlOptions options) { using (var exebits = new FileStream(exePath, FileMode.Open, FileAccess.Read)) { using (var pdbbits = new FileStream(pdbPath, FileMode.Open, FileAccess.Read)) { using (var sw = new StreamWriter(outPath, append: false, encoding: Encoding.UTF8)) { PdbToXmlConverter.ToXml(sw, pdbbits, exebits, options); } } } }
public static CompilationVerifier VerifyPdb( this CompilationVerifier verifier, string qualifiedMethodName, XElement expectedPdb, IMethodSymbol debugEntryPoint = null, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { verifier.Compilation.VerifyPdb(qualifiedMethodName, expectedPdb, debugEntryPoint, format, options, expectedValueSourceLine, expectedValueSourcePath); return(verifier); }
public static void GenXmlFromPdb(string exePath, string pdbPath, string outPath, PdbToXmlOptions options) { using (var exebits = new FileStream(exePath, FileMode.Open, FileAccess.Read)) { using (var pdbbits = new FileStream(pdbPath, FileMode.Open, FileAccess.Read)) { using (var sw = new StreamWriter(outPath, append: false, encoding: Encoding.UTF8)) { PdbToXmlConverter.ToXml(sw, pdbbits, exebits, options); } } } }
public unsafe static void ToXml(TextWriter xmlWriter, Stream pdbStream, Stream peStream, PdbToXmlOptions options = PdbToXmlOptions.Default, string methodName = null) { IEnumerable<MethodHandle> methodHandles; var headers = new PEHeaders(peStream); byte[] metadata = new byte[headers.MetadataSize]; peStream.Seek(headers.MetadataStartOffset, SeekOrigin.Begin); peStream.Read(metadata, 0, headers.MetadataSize); fixed (byte* metadataPtr = metadata) { var metadataReader = new MetadataReader((IntPtr)metadataPtr, metadata.Length); if (string.IsNullOrEmpty(methodName)) { methodHandles = metadataReader.MethodDefinitions; } else { var matching = metadataReader.MethodDefinitions. Where(methodHandle => GetQualifiedMethodName(metadataReader, methodHandle) == methodName).ToArray(); if (matching.Length == 0) { xmlWriter.WriteLine("<error>"); xmlWriter.WriteLine(string.Format("<message>No method '{0}' found in metadata.</message>", methodName)); xmlWriter.WriteLine("<available-methods>"); foreach (var methodHandle in metadataReader.MethodDefinitions) { xmlWriter.Write("<method><![CDATA["); xmlWriter.Write(GetQualifiedMethodName(metadataReader, methodHandle)); xmlWriter.Write("]]></method>"); xmlWriter.WriteLine(); } xmlWriter.WriteLine("</available-methods>"); xmlWriter.WriteLine("</error>"); return; } methodHandles = matching; } ToXml(xmlWriter, pdbStream, metadataReader, options, methodHandles); } }
private static void VerifyPdbImpl( this Compilation compilation, IMethodSymbol debugEntryPoint, string qualifiedMethodName, XElement expectedPdb, DebugInformationFormat format, PdbToXmlOptions options, int expectedValueSourceLine, string expectedValueSourcePath, bool expectedIsXmlLiteral) { Assert.NotEqual(DebugInformationFormat.Embedded, format); if (format == 0 || format == DebugInformationFormat.Pdb) { XElement actualNativePdb = XElement.Parse(GetPdbXml(compilation, debugEntryPoint, options, qualifiedMethodName, portable: false)); AssertXml.Equal(expectedPdb, actualNativePdb, expectedValueSourcePath, expectedValueSourceLine, expectedIsXmlLiteral); } if (format == 0 || format == DebugInformationFormat.PortablePdb) { XElement actualPortablePdb = XElement.Parse(GetPdbXml(compilation, debugEntryPoint, options, qualifiedMethodName, portable: true)); // SymWriter doesn't create empty scopes. When the C# compiler uses forwarding CDI instead of a NamespaceScope // the scope is actually not empty - it logically contains the imports. Portable PDB does not used forwarding and thus // creates the scope. When generating PDB XML for testing the Portable DiaSymReader returns empty namespaces. RemoveEmptyScopes(actualPortablePdb); // sharing the same expected output with native PDB if (format == 0) { RemoveNonPortablePdb(expectedPdb); // TODO: remove RemoveEmptySequencePoints(expectedPdb); // remove scopes that only contained non-portable elements (namespace scopes) RemoveEmptyScopes(expectedPdb); RemoveMethodsWithNoSequencePoints(expectedPdb); RemoveEmptyMethods(expectedPdb); } AssertXml.Equal(expectedPdb, actualPortablePdb, expectedValueSourcePath, expectedValueSourceLine, expectedIsXmlLiteral); } }
private void TestGeneratePdb([CallerMemberName] string testName = null) { const PdbToXmlOptions options = PdbToXmlOptions.IncludeEmbeddedSources | PdbToXmlOptions.ThrowOnError | PdbToXmlOptions.IncludeTokens | PdbToXmlOptions.ResolveTokens | PdbToXmlOptions.IncludeMethodSpans; string xmlFile = Path.Combine(TestCasePath, testName + ".xml"); string xmlContent = File.ReadAllText(xmlFile); XDocument document = XDocument.Parse(xmlContent); var files = document.Descendants("file").ToDictionary(f => f.Attribute("name").Value, f => f.Value); Tester.CompileCSharpWithPdb(Path.Combine(TestCasePath, testName + ".expected"), files); string peFileName = Path.Combine(TestCasePath, testName + ".expected.dll"); string pdbFileName = Path.Combine(TestCasePath, testName + ".expected.pdb"); var moduleDefinition = new PEFile(peFileName); var resolver = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchEntireImage); var decompiler = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings()); using (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, testName + ".pdb"), FileMode.OpenOrCreate, FileAccess.ReadWrite)) { pdbStream.SetLength(0); PortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream, noLogo: true); pdbStream.Position = 0; using (Stream peStream = File.OpenRead(peFileName)) using (Stream expectedPdbStream = File.OpenRead(pdbFileName)) { using (StreamWriter writer = new StreamWriter(Path.ChangeExtension(pdbFileName, ".xml"), false, Encoding.UTF8)) { PdbToXmlConverter.ToXml(writer, expectedPdbStream, peStream, options); } peStream.Position = 0; using (StreamWriter writer = new StreamWriter(Path.ChangeExtension(xmlFile, ".generated.xml"), false, Encoding.UTF8)) { PdbToXmlConverter.ToXml(writer, pdbStream, peStream, options); } } } string expectedFileName = Path.ChangeExtension(xmlFile, ".expected.xml"); ProcessXmlFile(expectedFileName); string generatedFileName = Path.ChangeExtension(xmlFile, ".generated.xml"); ProcessXmlFile(generatedFileName); Assert.AreEqual(Normalize(expectedFileName), Normalize(generatedFileName)); }
internal static void VerifyPdb( this Compilation compilation, string qualifiedMethodName, XElement expectedPdb, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { VerifyPdbImpl( compilation, qualifiedMethodName, expectedPdb, format, options, expectedValueSourceLine, expectedValueSourcePath, expectedIsXmlLiteral: true); }
private static void VerifyPdbMatchesExpectedXml( Stream peStream, Stream pdbStream, string qualifiedMethodName, PdbToXmlOptions pdbToXmlOptions, string expectedPdb, int expectedValueSourceLine, string expectedValueSourcePath, bool expectedIsXmlLiteral, bool isPortable ) { peStream.Position = 0; pdbStream.Position = 0; var actualPdb = XElement .Parse( PdbToXmlConverter.ToXml( pdbStream, peStream, pdbToXmlOptions, methodName: qualifiedMethodName ) ) .ToString(); var(actual, expected) = AdjustToPdbFormat( actualPdb, expectedPdb, actualIsPortable: isPortable, actualIsConverted: false ); AssertEx.AssertLinesEqual( expected, actual, $"PDB format: {(isPortable ? "Portable" : "Windows")}{Environment.NewLine}", expectedValueSourcePath, expectedValueSourceLine, escapeQuotes: !expectedIsXmlLiteral ); }
public static void VerifyPdb( this Compilation compilation, string qualifiedMethodName, string expectedPdb, IMethodSymbol debugEntryPoint = null, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { VerifyPdbImpl( compilation, debugEntryPoint, qualifiedMethodName, string.IsNullOrWhiteSpace(expectedPdb) ? "<symbols></symbols>" : expectedPdb, format, options, expectedValueSourceLine, expectedValueSourcePath, expectedIsXmlLiteral: false); }
internal static void VerifyPdb( this Compilation compilation, string qualifiedMethodName, string expectedPdb, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { var expectedPdbXml = XElement.Parse(string.IsNullOrWhiteSpace(expectedPdb) ? "<symbols></symbols>" : expectedPdb); VerifyPdbImpl( compilation, qualifiedMethodName, expectedPdbXml, format, options, expectedValueSourceLine, expectedValueSourcePath, expectedIsXmlLiteral: false); }
private static void VerifyConvertedPdbMatchesExpectedXml( Stream peStreamOriginal, Stream pdbStreamOriginal, string qualifiedMethodName, string expectedPdb, PdbToXmlOptions pdbToXmlOptions, bool expectedIsXmlLiteral, bool originalIsPortable) { var pdbStreamConverted = new MemoryStream(); var converter = new PdbConverter(diagnostic => Assert.True(false, diagnostic.ToString())); peStreamOriginal.Position = 0; pdbStreamOriginal.Position = 0; if (originalIsPortable) { converter.ConvertPortableToWindows(peStreamOriginal, pdbStreamOriginal, pdbStreamConverted); } else { converter.ConvertWindowsToPortable(peStreamOriginal, pdbStreamOriginal, pdbStreamConverted); } pdbStreamConverted.Position = 0; peStreamOriginal.Position = 0; var actualConverted = AdjustForConversionArtifacts(XElement.Parse(PdbToXmlConverter.ToXml(pdbStreamConverted, peStreamOriginal, pdbToXmlOptions, methodName: qualifiedMethodName)).ToString()); var adjustedExpected = AdjustForConversionArtifacts(expectedPdb); var(actual, expected) = AdjustToPdbFormat(actualConverted, adjustedExpected, actualIsPortable: !originalIsPortable, actualIsConverted: true); AssertEx.AssertLinesEqual( expected, actual, $"PDB format: {(originalIsPortable ? "Windows" : "Portable")} converted from {(originalIsPortable ? "Portable" : "Windows")}{Environment.NewLine}", expectedValueSourcePath: null, expectedValueSourceLine: 0, escapeQuotes: !expectedIsXmlLiteral); }
public static void VerifyPdb( this Compilation compilation, string qualifiedMethodName, XElement expectedPdb, IEnumerable <EmbeddedText> embeddedTexts = null, IMethodSymbol debugEntryPoint = null, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber] int expectedValueSourceLine = 0, [CallerFilePath] string expectedValueSourcePath = null) { VerifyPdbImpl( compilation, embeddedTexts, debugEntryPoint, qualifiedMethodName, expectedPdb.ToString(), format, options, expectedValueSourceLine, expectedValueSourcePath, expectedIsXmlLiteral: true); }
/// <summary> /// Load the PDB given the parameters at the ctor and spew it out to the XmlWriter specified /// at the ctor. /// </summary> private static void ToXml(TextWriter xmlWriter, Stream pdbStream, MetadataReader metadataReaderOpt, PdbToXmlOptions options, IEnumerable<MethodDefinitionHandle> methodHandles) { Debug.Assert(pdbStream != null); Debug.Assert((options & PdbToXmlOptions.ResolveTokens) == 0 || metadataReaderOpt != null); using (var writer = XmlWriter.Create(xmlWriter, s_xmlWriterSettings)) { // metadata reader is on stack -> no owner needed var symReader = SymReaderFactory.CreateReader(pdbStream, metadataReaderOpt, metadataMemoryOwnerOpt: null); try { var converter = new PdbToXmlConverter(writer, symReader, metadataReaderOpt, options); converter.WriteRoot(methodHandles ?? metadataReaderOpt.MethodDefinitions); } finally { ((ISymUnmanagedDispose)symReader).Destroy(); } } }
internal static void VerifyPdb( this Compilation compilation, string qualifiedMethodName, XElement expectedPdb, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber]int expectedValueSourceLine = 0, [CallerFilePath]string expectedValueSourcePath = null) { VerifyPdbImpl( compilation, qualifiedMethodName, expectedPdb, format, options, expectedValueSourceLine, expectedValueSourcePath, expectedIsXmlLiteral: true); }
internal static void VerifyPdb( this Compilation compilation, string qualifiedMethodName, string expectedPdb, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber]int expectedValueSourceLine = 0, [CallerFilePath]string expectedValueSourcePath = null) { var expectedPdbXml = XElement.Parse(string.IsNullOrWhiteSpace(expectedPdb) ? "<symbols></symbols>" : expectedPdb); VerifyPdbImpl( compilation, qualifiedMethodName, expectedPdbXml, format, options, expectedValueSourceLine, expectedValueSourcePath, expectedIsXmlLiteral: false); }
public static void GenXmlFromPdb(string exePath, string pdbPath, string outPath, PdbToXmlOptions options) { using (var peStream = new FileStream(exePath, FileMode.Open, FileAccess.Read)) using (var pdbStream = new FileStream(pdbPath, FileMode.Open, FileAccess.Read)) using (var dstFileStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite)) using (var sw = new StreamWriter(dstFileStream, Encoding.UTF8)) { PdbToXmlConverter.ToXml(sw, pdbStream, peStream, options); } }
/// <summary> /// Load the PDB given the parameters at the ctor and spew it out to the XmlWriter specified /// at the ctor. /// </summary> private static void ToXml(TextWriter xmlWriter, Stream pdbStream, MetadataReader metadataReaderOpt, PdbToXmlOptions options, IEnumerable<MethodHandle> methodHandles) { Debug.Assert(pdbStream != null); Debug.Assert((options & PdbToXmlOptions.ResolveTokens) == 0 || metadataReaderOpt != null); XmlDocument doc = new XmlDocument(); XmlWriter writer = doc.CreateNavigator().AppendChild(); using (TempPdbReader pdbReader = TempPdbReader.Create(pdbStream)) { if (pdbReader == null) { Console.WriteLine("Error: No Symbol Reader could be initialized."); } var converter = new PdbToXmlConverter(writer, pdbReader, metadataReaderOpt, options); converter.WriteRoot(methodHandles ?? metadataReaderOpt.MethodDefinitions); } writer.Close(); // Save xml to disk doc.Save(xmlWriter); }
/// <summary> /// Load the PDB given the parameters at the ctor and spew it out to the XmlWriter specified /// at the ctor. /// </summary> private static void ToXml(TextWriter xmlWriter, Stream pdbStream, MetadataReader metadataReaderOpt, PdbToXmlOptions options, IEnumerable <MethodDefinitionHandle> methodHandles) { Debug.Assert(pdbStream != null); Debug.Assert((options & PdbToXmlOptions.ResolveTokens) == 0 || metadataReaderOpt != null); XmlDocument doc = new XmlDocument(); XmlWriter writer = doc.CreateNavigator().AppendChild(); using (TempPdbReader pdbReader = TempPdbReader.Create(pdbStream)) { if (pdbReader == null) { Console.WriteLine("Error: No Symbol Reader could be initialized."); return; } var converter = new PdbToXmlConverter(writer, pdbReader, metadataReaderOpt, options); converter.WriteRoot(methodHandles ?? metadataReaderOpt.MethodDefinitions); } writer.Close(); // Save xml to disk doc.Save(xmlWriter); }
public static void GenXmlFromDeltaPdb(string pdbPath, string outPath, PdbToXmlOptions options) { using (var deltaPdb = new FileStream(pdbPath, FileMode.Open, FileAccess.Read)) { // There is no easy way to enumerate all method tokens that are present in the PDB. // So dump the first 255 method tokens (the ones that are not present will be skipped): File.WriteAllText(outPath, PdbToXmlConverter.DeltaPdbToXml(deltaPdb, Enumerable.Range(0x06000001, 255))); } }
public unsafe static void ToXml(TextWriter xmlWriter, Stream pdbStream, Stream peStream, PdbToXmlOptions options = PdbToXmlOptions.Default, string methodName = null) { IEnumerable <MethodDefinitionHandle> methodHandles; var headers = new PEHeaders(peStream); byte[] metadata = new byte[headers.MetadataSize]; peStream.Seek(headers.MetadataStartOffset, SeekOrigin.Begin); peStream.Read(metadata, 0, headers.MetadataSize); fixed(byte *metadataPtr = metadata) { var metadataReader = new MetadataReader(metadataPtr, metadata.Length); if (string.IsNullOrEmpty(methodName)) { methodHandles = metadataReader.MethodDefinitions; } else { var matching = metadataReader.MethodDefinitions. Where(methodHandle => GetQualifiedMethodName(metadataReader, methodHandle) == methodName).ToArray(); if (matching.Length == 0) { xmlWriter.WriteLine("<error>"); xmlWriter.WriteLine(string.Format("<message>No method '{0}' found in metadata.</message>", methodName)); xmlWriter.WriteLine("<available-methods>"); foreach (var methodHandle in metadataReader.MethodDefinitions) { xmlWriter.Write("<method><![CDATA["); xmlWriter.Write(GetQualifiedMethodName(metadataReader, methodHandle)); xmlWriter.Write("]]></method>"); xmlWriter.WriteLine(); } xmlWriter.WriteLine("</available-methods>"); xmlWriter.WriteLine("</error>"); return; } methodHandles = matching; } ToXml(xmlWriter, pdbStream, metadataReader, options, methodHandles); } }
internal static string GetPdbXml( Compilation compilation, PdbToXmlOptions options = 0, string qualifiedMethodName = "", bool portable = false) { string actual = null; using (var exebits = new MemoryStream()) { using (var pdbbits = new MemoryStream()) { compilation.Emit( exebits, pdbbits, options: EmitOptions.Default.WithDebugInformationFormat(portable ? DebugInformationFormat.PortablePdb : DebugInformationFormat.Pdb)); pdbbits.Position = 0; exebits.Position = 0; options |= PdbToXmlOptions.ResolveTokens | PdbToXmlOptions.ThrowOnError; actual = PdbToXmlConverter.ToXml(pdbbits, exebits, options, methodName: qualifiedMethodName); } ValidateDebugDirectory(exebits, compilation.AssemblyName + ".pdb", portable); } return actual; }
private static void VerifyPdbImpl( this Compilation compilation, string qualifiedMethodName, XElement expectedPdb, DebugInformationFormat format, PdbToXmlOptions options, int expectedValueSourceLine, string expectedValueSourcePath, bool expectedIsXmlLiteral) { Assert.NotEqual(DebugInformationFormat.Embedded, format); if (format == 0 || format == DebugInformationFormat.Pdb) { XElement actualNativePdb = XElement.Parse(GetPdbXml(compilation, options, qualifiedMethodName, portable: false)); AssertXml.Equal(expectedPdb, actualNativePdb, expectedValueSourcePath, expectedValueSourceLine, expectedIsXmlLiteral); } if (format == 0 || format == DebugInformationFormat.PortablePdb) { XElement actualPortablePdb = XElement.Parse(GetPdbXml(compilation, options, qualifiedMethodName, portable: true)); // SymWriter doesn't create empty scopes. When the C# compiler uses forwarding CDI instead of a NamespaceScope // the scope is actually not empty - it logically contains the imports. Portable PDB does not used forwarding and thus // creates the scope. When generating PDB XML for testing the Portable DiaSymReader returns empty namespaces. RemoveEmptyScopes(actualPortablePdb); // sharing the same expected output with native PDB if (format == 0) { RemoveNonPortablePdb(expectedPdb); // TODO: remove RemoveEmptySequencePoints(expectedPdb); // remove scopes that only contained non-portable elements (namespace scopes) RemoveEmptyScopes(expectedPdb); RemoveEmptyMethods(expectedPdb); } AssertXml.Equal(expectedPdb, actualPortablePdb, expectedValueSourcePath, expectedValueSourceLine, expectedIsXmlLiteral); } }
public CompilationVerifier VerifyPdb( string expectedPdb, IMethodSymbol debugEntryPoint = null, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber]int expectedValueSourceLine = 0, [CallerFilePath]string expectedValueSourcePath = null) { _compilation.VerifyPdb(expectedPdb, debugEntryPoint, format, options, expectedValueSourceLine, expectedValueSourcePath); return this; }
public static void CompileCSharpWithPdb(string assemblyName, Dictionary <string, string> sourceFiles, PdbToXmlOptions options) { var parseOptions = new CSharpParseOptions(languageVersion: Microsoft.CodeAnalysis.CSharp.LanguageVersion.Latest); List <EmbeddedText> embeddedTexts = new List <EmbeddedText>(); List <SyntaxTree> syntaxTrees = new List <SyntaxTree>(); foreach (KeyValuePair <string, string> file in sourceFiles) { var sourceText = SourceText.From(file.Value, new UTF8Encoding(false), SourceHashAlgorithm.Sha256); syntaxTrees.Add(SyntaxFactory.ParseSyntaxTree(sourceText, parseOptions, file.Key)); embeddedTexts.Add(EmbeddedText.FromSource(file.Key, sourceText)); } var compilation = CSharpCompilation.Create(Path.GetFileNameWithoutExtension(assemblyName), syntaxTrees, defaultReferences.Value, new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, platform: Platform.AnyCpu, optimizationLevel: OptimizationLevel.Release, allowUnsafe: true, deterministic: true )); using (FileStream peStream = File.Open(assemblyName + ".dll", FileMode.OpenOrCreate, FileAccess.ReadWrite)) using (FileStream pdbStream = File.Open(assemblyName + ".pdb", FileMode.OpenOrCreate, FileAccess.ReadWrite)) { var emitResult = compilation.Emit(peStream, pdbStream, options: new EmitOptions(debugInformationFormat: DebugInformationFormat.PortablePdb, pdbFilePath: assemblyName + ".pdb"), embeddedTexts: embeddedTexts); if (!emitResult.Success) { StringBuilder b = new StringBuilder("Compiler error:"); foreach (var diag in emitResult.Diagnostics) { b.AppendLine(diag.ToString()); } throw new Exception(b.ToString()); } } }
/// <summary> /// Load the PDB given the parameters at the ctor and spew it out to the XmlWriter specified /// at the ctor. /// </summary> private static void ToXml(TextWriter xmlWriter, Stream pdbStream, MetadataReader metadataReaderOpt, PdbToXmlOptions options, IEnumerable<MethodDefinitionHandle> methodHandles) { Debug.Assert(pdbStream != null); Debug.Assert((options & PdbToXmlOptions.ResolveTokens) == 0 || metadataReaderOpt != null); XmlDocument doc = new XmlDocument(); XmlWriter writer = doc.CreateNavigator().AppendChild(); using (SymReader symReader = new SymReader(pdbStream, metadataReaderOpt)) { var converter = new PdbToXmlConverter(writer, symReader, metadataReaderOpt, options); converter.WriteRoot(methodHandles ?? metadataReaderOpt.MethodDefinitions); } writer.Close(); // Save xml to disk doc.Save(xmlWriter); }
private PdbToXmlConverter(XmlWriter writer, TempPdbReader pdbReader, MetadataReader metadataReader, PdbToXmlOptions options) { this.pdbReader = pdbReader; this.metadataReader = metadataReader; this.writer = writer; this.options = options; }
public static string ToXml(Stream pdbStream, Stream peStream, PdbToXmlOptions options = PdbToXmlOptions.ResolveTokens, string methodName = null) { var writer = new StringWriter(); ToXml(writer, pdbStream, peStream, options, methodName); return writer.ToString(); }
public CompilationVerifier VerifyPdb( string qualifiedMethodName, XElement expectedPdb, DebugInformationFormat format = 0, PdbToXmlOptions options = 0, [CallerLineNumber]int expectedValueSourceLine = 0, [CallerFilePath]string expectedValueSourcePath = null) { _compilation.VerifyPdb(qualifiedMethodName, expectedPdb, format, options, expectedValueSourceLine, expectedValueSourcePath); return this; }
public static string ToXml(Stream pdbStream, byte[] peImage, PdbToXmlOptions options = PdbToXmlOptions.ResolveTokens, string methodName = null) { var writer = new StringWriter(); ToXml(writer, pdbStream, new MemoryStream(peImage), options, methodName); return writer.ToString(); }