private ReportAnalysis Read(ISymbolReader reader, ICoverageModule module) { var lines = new List<BlockLineRange>(); var result = new ReportAnalysis(); //These are unused uint id; string name; string uName; string cName; string aName; byte[] coverageBuffer = module.GetCoverageBuffer(null); while (reader.GetNextMethod(out id, out name, out uName, out cName, out aName, lines)) { var stats = CoverageInfo.GetMethodStatistics(coverageBuffer, lines); result.LinesCovered += stats.LinesCovered; result.LinesPartiallyCovered += stats.LinesPartiallyCovered; result.LinesNotCovered += stats.LinesNotCovered; lines.Clear(); } return result; }
public LocalVariableNameReader(MethodInfo m) { ISymbolReader symReader = SymUtil.GetSymbolReaderForFile(m.DeclaringType.Assembly.Location, null); ISymbolMethod met = symReader.GetMethod(new SymbolToken(m.MetadataToken)); VisitLocals(met.RootScope); }
public override bool Execute() { string pdbxmlFile = Path.ChangeExtension(AssemblyName.ItemSpec, ".pdb.xml"); _pddxmlFile = new TaskItem(pdbxmlFile); xwriter = new XmlTextWriter(pdbxmlFile, null); xwriter.Formatting = Formatting.Indented; //Log.LogMessage("Get symbol reader for file {0}", Path.ChangeExtension(AssemblyName.ItemSpec, ".pdb")); ISymbolReader reader = SymUtil.GetSymbolReaderForFile(AssemblyName.ItemSpec, null); //Log.LogMessage("Load assembly"); m_assembly = System.Reflection.Assembly.LoadFrom(AssemblyName.ItemSpec); // Begin writing XML. xwriter.WriteStartDocument(); xwriter.WriteComment("This is an XML file representing the PDB for '" + AssemblyName.ItemSpec + "'"); xwriter.WriteStartElement("Types"); // Record what input file these symbols are for. xwriter.WriteAttributeString("file", AssemblyName.ItemSpec); //WriteDocList(reader); WriteTypesAndDocs(reader); xwriter.WriteEndElement(); // "Symbols"; xwriter.Close(); return !Log.HasLoggedErrors; }
// Dump all of the methods in the given ISymbolReader to the XmlWriter provided in the ctor. void WriteTypesAndDocs(ISymbolReader reader) { //Log.LogMessage("Write Types and Docs"); // Use reflection to enumerate all methods foreach (Type t in m_assembly.GetTypes()) { Dictionary<string, int> uniqDocs = GetUniqDocs(reader, t); if (uniqDocs.Count == 0) { Debug.WriteLine(string.Format("Type {0} does not have any methods. Unable to determine which file defines this type", t.Name)); //Log.LogWarning("Type {0} does not have any methods. Unable to determine which file defines this type",t.Name); continue; } xwriter.WriteStartElement("Type"); xwriter.WriteAttributeString("Name", t.FullName); foreach (string doc in uniqDocs.Keys) { xwriter.WriteStartElement("File"); xwriter.WriteAttributeString("Name",doc); xwriter.WriteEndElement(); } xwriter.WriteEndElement(); // type } }
private void ReadMethodBody() { this.MoveTo(this.method.RVA); byte num = base.ReadByte(); int num1 = num & 3; if (num1 == 2) { this.body.code_size = num >> 2; this.body.MaxStackSize = 8; this.ReadCode(); } else { if (num1 != 3) { throw new InvalidOperationException(); } this.position--; this.ReadFatMethod(); } ISymbolReader symbolReader = this.reader.module.symbol_reader; if (symbolReader != null) { Collection <Instruction> instructions = this.body.Instructions; symbolReader.Read(this.body, (int offset) => CodeReader.GetInstruction(instructions, offset)); } }
void WriteDocList(ISymbolReader reader) { xwriter.WriteComment("This is a list of all source files referred by the PDB."); int id = 0; // Write doc list xwriter.WriteStartElement("files"); { ISymbolDocument[] docs = reader.GetDocuments(); foreach (ISymbolDocument doc in docs) { string url = doc.URL; // Symbol store may give out duplicate documents. We'll fold them here if (m_fileMapping.ContainsKey(url)) { xwriter.WriteComment("There is a duplicate entry for: " + url); continue; } id++; m_fileMapping.Add(doc.URL, id); xwriter.WriteStartElement("file"); { xwriter.WriteAttributeString("id", id.ToString()); xwriter.WriteAttributeString("name", doc.URL); } xwriter.WriteEndElement(); // file } } xwriter.WriteEndElement(); // files }
void OnModuleLoad(object sender, CorModuleEventArgs e) { CorMetadataImport mi = new CorMetadataImport(e.Module); // Required to avoid the jit to get rid of variables too early e.Module.JITCompilerFlags = CorDebugJITCompilerFlags.CORDEBUG_JIT_DISABLE_OPTIMIZATION; string file = e.Module.Assembly.Name; lock (documents) { ISymbolReader reader = null; if (file.IndexOfAny(System.IO.Path.InvalidPathChars) == -1 && System.IO.File.Exists(System.IO.Path.ChangeExtension(file, ".pdb"))) { try { reader = symbolBinder.GetReaderForFile(mi.RawCOMObject, file, "."); foreach (ISymbolDocument doc in reader.GetDocuments()) { if (string.IsNullOrEmpty(doc.URL)) { continue; } string docFile = System.IO.Path.GetFullPath(doc.URL); DocInfo di = new DocInfo(); di.Document = doc; di.Reader = reader; di.Module = e.Module; documents[docFile] = di; NotifySourceFileLoaded(docFile); } } catch (Exception ex) { OnDebuggerOutput(true, string.Format("Debugger Error: {0}\n", ex.Message)); } e.Module.SetJmcStatus(true, null); } else { // Flag modules without debug info as not JMC. In this way // the debugger won't try to step into them e.Module.SetJmcStatus(false, null); } ModuleInfo moi; if (modules.TryGetValue(e.Module.Name, out moi)) { moi.References++; } else { moi = new ModuleInfo(); moi.Module = e.Module; moi.Reader = reader; moi.Importer = mi; moi.References = 1; modules[e.Module.Name] = moi; } } e.Continue = true; }
internal BfAssembly(BfCache cache, AssemblyDefinition assemblyDef, bool isCoreAssembly, string rootDirectory) { this.int_0 = cache.method_15(); this.assemblyDefinition_0 = assemblyDef; this.string_1 = assemblyDef.Name.Name; this.bool_0 = isCoreAssembly; this.string_0 = this.assemblyDefinition_0.Name.Version.ToString(); try { PdbFactory pdbFactory = new PdbFactory(); string text = Path.Combine(rootDirectory, this.assemblyDefinition_0.Name.Name + ".dll"); if (System.IO.File.Exists(text)) { this.isymbolReader_0 = pdbFactory.CreateReader(null, text); } text = Path.Combine(rootDirectory, this.assemblyDefinition_0.Name.Name + ".exe"); if (System.IO.File.Exists(text)) { this.isymbolReader_0 = pdbFactory.CreateReader(null, text); } } catch (Exception ex) { Logger.LogWarning("AssemblyConstructor", "Something went wrong " + ex.ToString()); } }
/// <summary> /// Gets information about the source if it is available. /// </summary> private bool GetSourceReference() { try { ISymbolReader sr = SymUtil.GetSymbolReaderForFile(_method.Module.Assembly.Location, null); ISymbolMethod sm = sr.GetMethod(new SymbolToken(_method.MetadataToken)); _count = sm.SequencePointCount; _offsets = new int[_count]; _documents = new ISymbolDocument[_count]; _startColumns = new int[_count]; _endColumns = new int[_count]; _startRows = new int[_count]; _endRows = new int[_count]; sm.GetSequencePoints(_offsets, _documents, _startRows, _startColumns, _endRows, _endColumns); return(true); } catch { _count = 0; _offsets = null; _documents = null; _startColumns = null; _endColumns = null; _startRows = null; _endRows = null; return(false); } }
private void LoadSourceCodeForTypes(IEnumerable <TypeDefinition> types, ISymbolReader reader) { foreach (var typeDefinition in types) { foreach (var method in typeDefinition.Methods.Where(m => m.HasBody)) { MethodDefinition capturedMethod = method; reader.Read(capturedMethod.Body, o => capturedMethod.Body.Instructions.FirstOrDefault(i => i.Offset >= o)); var sourceFiles = method.Body.Instructions.Where(i => i.SequencePoint != null) .Select(i => i.SequencePoint.Document.Url) .Distinct(); foreach (var sourceFile in sourceFiles) { if (!SourceFiles.ContainsKey(sourceFile) && File.Exists(sourceFile)) { SourceFiles.Add(sourceFile, File.ReadAllLines(sourceFile)); } } } if (typeDefinition.NestedTypes != null) { LoadSourceCodeForTypes(typeDefinition.NestedTypes, reader); } } }
/// <summary> /// Reloads the symbols for the module. /// </summary> /// <param name="force">Forces reloading of symbols that have already been successfully loaded.</param> public void ReloadSymbols(bool force) { if (m_isSymReaderInitialized == false) { return; } if (m_isSymReaderInitialized && m_symReader != null && !force) { return; // we don't want to reload symbols that has been sucessfully loaded } if (EditsCounter > 0) { throw new MDbgException("Cannot reload symbols for edited module " + CorModule.Name); } // MdbgFunctions cache symbol information. This doesn't reset that cached info. m_isSymReaderInitialized = false; m_symReader = null; // clear the cache of functions. This is necessary since the cache contains also // information from symbol files. Reloding the files might cause the information // in the cache to become stale. m_functions.Clear(); }
// Initializes all private symbol variables private void SetupSymbolInformation() { if (p_symbolsInitialized) { return; } p_symbolsInitialized = true; CorModule module = GetModule(); ISymbolReader symreader = module.GetSymbolReader(); p_hasSymbols = symreader != null; if (p_hasSymbols) { ISymbolMethod sm = null; sm = symreader.GetMethod(new SymbolToken((Int32)GetToken())); // FIXME add version if (sm == null) { p_hasSymbols = false; return; } p_symMethod = sm; p_SPcount = p_symMethod.SequencePointCount; p_SPoffsets = new Int32[p_SPcount]; p_SPdocuments = new ISymbolDocument[p_SPcount]; p_SPstartLines = new Int32[p_SPcount]; p_SPendLines = new Int32[p_SPcount]; p_SPstartColumns = new Int32[p_SPcount]; p_SPendColumns = new Int32[p_SPcount]; p_symMethod.GetSequencePoints(p_SPoffsets, p_SPdocuments, p_SPstartLines, p_SPstartColumns, p_SPendLines, p_SPendColumns); } }
public void Convert() { xmlWriter.WriteStartDocument(); xmlWriter.WriteStartElement("symbols"); xmlWriter.WriteAttributeString("program", "PdbConvert"); xmlWriter.WriteAttributeString("version", "1"); AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve; string currDir = Environment.CurrentDirectory; foreach (string fileName in assemblyFileNames) { // Change to the file's directory so that we can find referenced assemblies Environment.CurrentDirectory = Path.GetDirectoryName(fileName); ISymbolReader reader = SymbolAccess.GetReaderForFile(fileName); assembly = Assembly.ReflectionOnlyLoadFrom(fileName); xmlWriter.WriteStartElement("module"); xmlWriter.WriteAttributeString("file", Path.GetFileName(fileName).ToLowerInvariant()); xmlWriter.WriteAttributeString("version", GetAssemblyVersion(assembly)); xmlWriter.WriteAttributeString("config", GetAssemblyConfiguration(assembly)); WriteDocList(reader); //WriteEntryPoint(reader); WriteAllMethods(reader); xmlWriter.WriteEndElement(); // </module> } Environment.CurrentDirectory = currDir; AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= CurrentDomain_ReflectionOnlyAssemblyResolve; xmlWriter.WriteEndElement(); // </symbols> }
public ISymbolReader LoadPdbForModule(ModuleDefinition module) { using (Tracer t = new Tracer(myType, "LoadPdbForModule")) { string fileName = module.Assembly.MainModule.FullyQualifiedName; t.Info("Module file name: {0}", fileName); ISymbolReader reader = null; if (!this.myFile2PdbMap.TryGetValue(fileName, out reader)) { if (this.myFailedPdbs.Contains(fileName)) { t.Warning("This pdb could not be successfully downloaded"); return(reader); } for (int i = 0; i < 2; i++) { try { reader = this.myPdbFactory.GetSymbolReader(module, fileName); this.myFile2PdbMap[fileName] = reader; break; } catch (Exception ex) { t.Error(Level.L3, ex, "Pdb did not match or it is not present"); string pdbFileName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".pdb"); try { File.Delete(pdbFileName); } catch (Exception delex) { t.Error(Level.L2, delex, "Could not delete pdb {0}", pdbFileName); } // When we have symbol server we try to make us of it for matches. if (String.IsNullOrEmpty(this.mySymbolServer)) { break; } t.Info("Try to download pdb from symbol server {0}", this.mySymbolServer); bool bDownloaded = this.myDownLoader.DownloadPdbs(new FileQuery(fileName), this.mySymbolServer); t.Info("Did download pdb {0} from symbol server with return code: {1}", fileName, bDownloaded); if (bDownloaded == false || i == 1) // second try did not work out as well { this.myFailedPdbs.Add(fileName); break; } } } } return(reader); } }
/// <summary> /// Load the PDB given the parameters at the ctor and spew it out to the XmlWriter specified /// at the ctor. /// </summary> public SymbolData ReadSymbols() { // Actually load the files ISymbolReader reader = SymbolAccess.GetReaderForFile(m_symFormat, m_assemblyPath, null); if (reader == null) { Console.WriteLine("Error: No matching PDB could be found for the specified assembly."); return(null); } AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve); m_assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(m_assemblyPath); m_fileMapping = new Dictionary <string, int>(); SymbolData symbolData = new SymbolData(); // Record what input file these symbols are for. symbolData.assembly = m_assemblyPath; symbolData.entryPointToken = ReadEntryPoint(reader); symbolData.sourceFiles = ReadDocList(reader); symbolData.methods = ReadAllMethods(reader); return(symbolData); }
public void ReadSymbols(ISymbolReader reader, bool throwIfSymbolsAreNotMaching) { if (reader == null) { throw new ArgumentNullException("reader"); } symbol_reader = reader; if (!symbol_reader.ProcessDebugHeader(GetDebugHeader())) { symbol_reader = null; if (throwIfSymbolsAreNotMaching) { throw new SymbolsNotMatchingException("Symbols were found but are not matching the assembly"); } return; } if (HasImage && ReadingMode == ReadingMode.Immediate) { var immediate_reader = new ImmediateModuleReader(Image); immediate_reader.ReadSymbols(this); } }
private void ReadMethodBody() { this.MoveTo(this.method.RVA); byte b = base.ReadByte(); switch (b & 3) { case 2: this.body.code_size = b >> 2; this.body.MaxStackSize = 8; this.ReadCode(); break; case 3: this.position--; this.ReadFatMethod(); break; default: throw new InvalidOperationException(); } ISymbolReader symbol_reader = this.reader.module.symbol_reader; if (symbol_reader != null) { Collection <Instruction> instructions = this.body.Instructions; symbol_reader.Read(this.body, (int offset) => CodeReader.GetInstruction(instructions, offset)); } }
// Write all docs, and add to the m_fileMapping list. // Other references to docs will then just refer to this list. private void WriteDocList(ISymbolReader reader) { int id = 0; xmlWriter.WriteStartElement("files"); { foreach (ISymbolDocument doc in reader.GetDocuments()) { string url = doc.URL; // Symbol store may give out duplicate documents if (fileMapping.ContainsKey(url)) { continue; } id++; fileMapping.Add(doc.URL, id); string srcFileName = doc.URL; if (!string.IsNullOrEmpty(SourceBasePath) && srcFileName.StartsWith(SourceBasePath, StringComparison.OrdinalIgnoreCase)) { srcFileName = srcFileName.Substring(SourceBasePath.Length).TrimStart('\\'); } xmlWriter.WriteStartElement("file"); xmlWriter.WriteAttributeString("id", id.ToString()); xmlWriter.WriteAttributeString("name", srcFileName); xmlWriter.WriteEndElement(); // </file> } } xmlWriter.WriteEndElement(); // </files> }
/// <summary> /// Returns the name of the file for the given method using the given symbol reader /// </summary> /// <param name="reader">The reader to use</param> /// <param name="methodBase">The method to lookup</param> /// <returns>The file containing the method or null.</returns> private static string GetFileForMethod(ISymbolReader reader, MethodBase methodBase) { int token = methodBase.MetadataToken; ISymbolMethod methodSymbol = reader == null ? null : reader.GetMethod(new SymbolToken(token)); if (methodSymbol != null) { int count = methodSymbol.SequencePointCount; // Get the sequence points from the symbol store. // We could cache these arrays and reuse them. int[] offsets = new int[count]; ISymbolDocument[] docs = new ISymbolDocument[count]; int[] startColumn = new int[count]; int[] endColumn = new int[count]; int[] startRow = new int[count]; int[] endRow = new int[count]; methodSymbol.GetSequencePoints(offsets, docs, startRow, startColumn, endRow, endColumn); foreach (ISymbolDocument doc in docs) { string file = doc.URL.ToString(); return(file); } } return(null); }
public void loadAndMapSymbols(AssemblyDefinition assemblyDefinition, string assemblyPath, bool decompileCodeIfNoPdb, string pathToSaveDecompiledSourceCode) { try { if (assemblyPath != null) { var pdbFile = assemblyPath.Replace(Path.GetExtension(assemblyPath), ".pdb"); if (File.Exists(pdbFile)) { string unit = assemblyPath; ModuleDefinition modDef = assemblyDefinition.MainModule; var pdbFactory = new PdbFactory(); ISymbolReader reader = pdbFactory.CreateReader(modDef, unit); modDef.LoadSymbols(reader); } else { if (decompileCodeIfNoPdb) { new CecilDecompiler().decompile(assemblyDefinition, pathToSaveDecompiledSourceCode); } } } } catch (Exception ex) { PublicDI.log.error("in loadAndMapSymbols: {0]", ex.Message); } }
internal BfAssembly(AssemblyDefinition assemblyDef, bool isCoreAssembly, string rootDirectory) { _assemblyDefinition = assemblyDef; Name = assemblyDef.Name.Name; IsCoreAssembly = isCoreAssembly; Version = _assemblyDefinition.Name.Version.ToString(); try { var dllFileName = Path.Combine(rootDirectory, $"{_assemblyDefinition.Name.Name}.dll"); var exeFileName = Path.Combine(rootDirectory, $"{_assemblyDefinition.Name.Name}.exe"); string file = null; if (File.Exists(dllFileName)) { file = dllFileName; } else if (File.Exists(exeFileName)) { file = exeFileName; } _symbolReader = new PdbReaderProvider().GetSymbolReader(null, file); } // ReSharper disable once EmptyGeneralCatchClause // ReSharper disable once UnusedVariable catch (Exception ex) { } }
private List <SymAttribute> ReadSymAttributes(ISymbolReader reader, ISymbolMethod method, bool haveCSharpCDI) { List <SymAttribute> attrs = new List <SymAttribute>(); foreach (string name in AttributeNamesToSearch()) { // If this attirubte represents C# CDI data, and we were able to expand it, then indicate that // the attribute here is redundant (as a raw view) and shouldn't be included again. if (name == k_cSharpCDIAttrName && haveCSharpCDI) { continue; } // Note that despite being defined on ISymbolReader instead of ISymbolMethod, custom // attributes are permitted only on method metadata tokens. byte[] attrVal = reader.GetSymAttribute(method.Token, name); if (attrVal != null) { SymAttribute attr = new SymAttribute(); attr.name = name; attr.value = Util.ToHexString(attrVal); attrs.Add(attr); } } return(attrs); }
/// <summary> /// Indexer that gets the <see cref="ISymbolReader"/> appropriate to analyze /// the specified <paramref name="type"/>. This indexer caches by Assembly. /// </summary> /// <param name="type">The type we will analyze.</param> /// <returns>A <see cref="ISymbolReader"/> or <c>null</c> if one is not available.</returns> internal ISymbolReader this[Type type] { get { Debug.Assert(type != null, "The type is required"); Assembly assembly = type.Assembly; ISymbolReader reader = null; // Lazily create the readers for assemblies we have not yet encountered. if (!this._symbolReadersByType.TryGetValue(assembly, out reader)) { // We don't create symbol readers for System assemblies if (!assembly.IsSystemAssembly()) { // Lazy create. Note that a null is a legal result and will // be cached to avoid redundant failures reader = this.CreateSymbolReader(assembly); } this._symbolReadersByType[assembly] = reader; } return(reader); } }
private void ProcessInnerParenthesis(ISymbol <string, string> readed, ISymbolReader <string, string> reader) { var parenthesisStatus = 1; this.currentReadingValues.Add(readed); do { if (reader.IsAtEOF()) { throw new OdmpProblemException("Matriz set is in a wrong format."); } else { readed = reader.Get(); if (this.elementsDelimiterTypes.ContainsKey(readed.SymbolType)) { this.ProcessDelimiteres(readed, reader); } else if (readed.SymbolType == "left_parenthesis") { ++parenthesisStatus; } else if (readed.SymbolType == "right_parenthesis") { --parenthesisStatus; } this.currentReadingValues.Add(readed); } } while (parenthesisStatus > 0); }
// Write all docs, and add to the m_fileMapping list. // Other references to docs will then just refer to this list. private List <Document> ReadDocList(ISymbolReader reader) { List <Document> docs = new List <Document>(); int id = 0; foreach (ISymbolDocument doc in reader.GetDocuments()) { Document docData = new Document(); string url = doc.URL; // Symbol store may give out duplicate documents. We'll fold them here if (fileMapping.ContainsKey(url)) { continue; } id++; fileMapping.Add(url, id); docData.id = id; docData.checksum = Convert.ToBase64String(doc.GetCheckSum()); docData.url = url; docData.language = doc.Language; docData.languageVendor = doc.LanguageVendor; docData.documentType = doc.DocumentType; docs.Add(docData); } return(docs); }
// Write out a reference to the entry point method (if one exists) void WriteEntryPoint(ISymbolReader reader) { try { // If there is no entry point token (such as in a dll), this will throw. SymbolToken token = reader.UserEntryPoint; ISymbolMethod m = reader.GetMethod(token); Debug.Assert(m != null); // would have thrown by now. // Should not throw past this point m_writer.WriteComment( "This is the token for the 'entry point' method, which is the method that will be called when the assembly is loaded." + " This usually corresponds to 'Main'"); m_writer.WriteStartElement("EntryPoint"); WriteMethod(m); m_writer.WriteEndElement(); } catch (System.Runtime.InteropServices.COMException) { // If the Symbol APIs fail when looking for an entry point token, there is no entry point. m_writer.WriteComment( "There is no entry point token such as a 'Main' method. This module is probably a '.dll'"); } }
static void Main(string[] args) { Assembly ass = Assembly.GetExecutingAssembly(); ISymbolReader symreader = SymUtil.GetSymbolReaderForFile(ass.Location, null); MethodInfo m = ass.GetType("PdbTest.TestClass").GetMethod("GetStringRepresentation"); ISymbolMethod met = symreader.GetMethod(new SymbolToken(m.MetadataToken)); int count = met.SequencePointCount; ISymbolDocument[] docs = new ISymbolDocument[count]; int[] offsets = new int[count]; int[] lines = new int[count]; int[] columns = new int[count]; int[] endlines = new int[count]; int[] endcolumns = new int[count]; met.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns); StreamReader reader = new StreamReader(docs[0].URL); string[] linesOfCode = reader.ReadToEnd().Split('n'); reader.Close(); Console.WriteLine("The content of method PdbTest.TestClass.GetStringRepresentation"); for (int i = lines[0]; i < endlines[count - 1] - 1; i++) { Console.WriteLine(linesOfCode[i]); } }
private void ReadMethodBody() { byte b = ReadByte(); switch (b & 3) { case 2: body.code_size = b >> 2; body.MaxStackSize = 8; ReadCode(); break; case 3: base.Advance(-1); ReadFatMethod(); break; default: throw new InvalidOperationException(); } ISymbolReader symbol_reader = reader.module.symbol_reader; if (symbol_reader != null && method.debug_info == null) { method.debug_info = symbol_reader.Read(method); } if (method.debug_info != null) { ReadDebugInfo(); } }
private void ReadMethodBody() { byte flags = ReadByte(); switch (flags & 0x3) { case 0x2: // tiny body.code_size = flags >> 2; body.MaxStackSize = 8; ReadCode(); break; case 0x3: // fat Advance(-1); ReadFatMethod(); break; default: throw new InvalidOperationException(); } ISymbolReader symbol_reader = _reader.module.symbol_reader; if (symbol_reader is not null && _method.debug_info is null) { _method.debug_info = symbol_reader.Read(_method); } if (_method.debug_info is not null) { ReadDebugInfo(); } }
public void Dispose() { if (DebugData != null) { DebugData.Dispose(); DebugData = null; } }
private static void OutputModule(ISymbolReader pdbReader, ModuleDefinition module) { Console.WriteLine("\t" + module.FullyQualifiedName); foreach (TypeDefinition type in module.Types) { OutputType(pdbReader, type); } }
private static void OutputMethod(ISymbolReader pdbReader, MethodDefinition method) { Console.WriteLine("\t\t\t" + method.FullName); foreach (Instruction instruction in method.Body.Instructions) { Console.WriteLine("\t\t\t\t" + instruction.OpCode.ToString()); } }
private static void OutputAssembly(ISymbolReader pdbReader, AssemblyDefinition asm) { Console.WriteLine(asm.FullName); foreach (var module in asm.Modules) { OutputModule(pdbReader, module); } }
private void setBreakpointThroughDocument(CorModule module, ISymbolReader reader) { foreach (var doc in reader.GetDocuments()) { if (attemptSetBreakpoint(reader, doc, module)) return; } }
public void Dispose() { if (_reader is IDisposable disposableReader) { disposableReader.Dispose(); } _reader = null; }
private static void OutputType(ISymbolReader pdbReader, TypeDefinition type) { Console.WriteLine("\t\t" + type.FullName); foreach (MethodDefinition method in type.Methods) { OutputMethod(pdbReader, method); } Console.WriteLine(); }
public void Set(CorModule module, ISymbolReader reader) { if (_breakpoint.File == null) { setBreakpointThroughModule(module, reader); return; } setBreakpointThroughDocument(module, reader); }
public void Dispose() { if (this.symReader != null) { ((IDisposable)this.symReader).Dispose(); this.symReader = null; this.rawReader = null; } }
private COR_DEBUG_STEP_RANGE[] getStepRanges(CorFrame frame, ISymbolReader reader, uint offset) { var method = reader.GetMethod(new SymbolToken(frame.FunctionToken)); foreach (var sp in new SequencePointFactory().Generate(method)) { if (sp.Offset > offset) return createStepRange(offset, sp.Offset); } return null; }
/// <summary> /// Constructor /// </summary> /// <param name="reader">A <see cref="ISymbolReader"/> instance</param> /// <param name="module">Owner module</param> public PdbState(ISymbolReader reader, ModuleDefMD module) { if (reader == null) throw new ArgumentNullException("reader"); if (module == null) throw new ArgumentNullException("module"); this.reader = reader; this.userEntryPoint = module.ResolveToken(reader.UserEntryPoint.GetToken()) as MethodDef; foreach (var doc in reader.GetDocuments()) Add_NoLock(new PdbDocument(doc)); }
private bool attemptSetBreakpoint(ISymbolReader reader, ISymbolDocument doc, CorModule module) { if (!doc.URL.Equals(_breakpoint.File)) return false; var line = doc.FindClosestLine(_breakpoint.Line); var method = reader.GetMethodFromDocumentPosition(doc, line, _breakpoint.Column); var function = module.GetFunctionFromToken(method.Token.GetToken()); var wasSet = attemptToSetBreakpointThroughSequencePoints(doc, line, method, function); if (!wasSet) setBreakpointThroughFunction(function); return true; }
/// <summary> /// Called when receiving a report about an assembly /// </summary> /// <param name="domainIndex"></param> /// <param name="domainName"></param> /// <param name="assemblyName"></param> /// <param name="moduleName"></param> public void EnterAssembly(int domainIndex, string domainName, string assemblyName, string moduleName) { _symbolReader = _symbolReaderFactory.GetSymbolReader(moduleName); if (_symbolReader != null) { var docs = _symbolReader.GetDocuments(); foreach (var doc in docs) { RegisterFile(doc.URL); } } Report.Assemblies.Add(currentAssembly = new AssemblyEntry { AssemblyRef = Report.Assemblies.Count + 1, Module = moduleName, Name = assemblyName, Domain = domainName, DomainIndex = domainIndex }); }
public bool InitSymbolResolver(SymbolResolverContextInfo context) { symbolReader = new DefaultSymbolReader(context); contextInfo = context; TraceEventNativeMethods.SymSetOptions( TraceEventNativeMethods.SymOptions.SYMOPT_DEBUG | TraceEventNativeMethods.SymOptions.SYMOPT_CASE_INSENSITIVE | // TraceEventNativeMethods.SymOptions.SYMOPT_DEFERRED_LOADS | //TraceEventNativeMethods.SymOptions.SYMOPT_LOAD_LINES | TraceEventNativeMethods.SymOptions.SYMOPT_EXACT_SYMBOLS | TraceEventNativeMethods.SymOptions.SYMOPT_UNDNAME // undecorated names ); // for testing purpose Environment.SetEnvironmentVariable("_NT_SYMBOL_PATH", @"SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols"); bool bInit = TraceEventNativeMethods.SymInitializeW(contextInfo.currentProcessHandle, null, false); if (bInit) { registerCallback = new TraceEventNativeMethods.SymRegisterCallbackProc(SymRegisterCallbackProcInfo); TraceEventNativeMethods.SymRegisterCallbackW64(contextInfo.currentProcessHandle, registerCallback, 0); } return bInit; }
/// <summary> /// Loads symbols using <paramref name="symbolReader"/> /// </summary> /// <param name="symbolReader">PDB symbol reader</param> public void LoadPdb(ISymbolReader symbolReader) { if (symbolReader == null) return; if (pdbState != null) throw new InvalidOperationException("PDB file has already been initialized"); var orig = Interlocked.CompareExchange(ref pdbState, new PdbState(symbolReader, this), null); if (orig != null) throw new InvalidOperationException("PDB file has already been initialized"); }
/// <summary> /// Reloads the symbols for the module. /// </summary> /// <param name="force">Forces reloading of symbols that have already been successfully loaded.</param> public void ReloadSymbols(bool force) { if (m_isSymReaderInitialized == false) return; if (m_isSymReaderInitialized && m_symReader != null && !force) return; // we don't want to reload symbols that has been sucessfully loaded if (EditsCounter > 0) throw new MDbgException("Cannot reload symbols for edited module " + CorModule.Name); // MdbgFunctions cache symbol information. This doesn't reset that cached info. m_isSymReaderInitialized = false; m_symReader = null; // clear the cache of functions. This is necessary since the cache contains also // information from symbol files. Reloding the files might cause the information // in the cache to become stale. m_functions.Clear(); }
/// <summary> /// Updates the symbols for a module given a new reader object /// </summary> /// <param name="newSymReader">The new symbol reader object</param> private void UpdateSymbols(ISymbolReader newSymReader) { // replace symbol reader with the updated one. m_symReader = newSymReader; m_isSymReaderInitialized = true; // Reset the cache of MDbgFunction objects since their symbol information is now // possibly out-of-date. // Note that in practice UpdateModuleSymbols is really only used to add symbols // for newly emitted types. This means we could probably get away with something // lighter weight, like looping through the MDbgFunction objects, finding ones // with missing symbol info, and resetting their m_isInitialized to false. But this // would leave multiple symbol readers alive, taking up memory etc. It's better // to throw away all references to the old symbol reader and recreate everything // for the new reader. m_functions.Clear(); }
// Write all docs, and add to the m_fileMapping list. // Other references to docs will then just refer to this list. private void WriteDocList(ISymbolReader reader) { m_writer.WriteComment("This is a list of all source files referred by the PDB."); int id = 0; // Write doc list m_writer.WriteStartElement("files"); { ISymbolDocument[] docs = reader.GetDocuments(); foreach (ISymbolDocument doc in docs) { string url = doc.URL; // Symbol store may give out duplicate documents. We'll fold them here if (m_fileMapping.ContainsKey(url)) { m_writer.WriteComment("There is a duplicate entry for: " + url); continue; } id++; m_fileMapping.Add(doc.URL, id); m_writer.WriteStartElement("file"); { m_writer.WriteAttributeString("id", Util.CultureInvariantToString(id)); m_writer.WriteAttributeString("name", doc.URL); m_writer.WriteAttributeString("language", doc.Language.ToString()); m_writer.WriteAttributeString("languageVendor", doc.LanguageVendor.ToString()); m_writer.WriteAttributeString("documentType", doc.DocumentType.ToString()); } m_writer.WriteEndElement(); // file } } m_writer.WriteEndElement(); // files }
public void AddSymbolReader (AssemblyDefinition assembly, ISymbolReader symbolReader) { symbol_readers [assembly] = symbolReader; }
private void setBreakpoint(CorModule module, ISymbolReader reader) { var setter = new BreakpointSetter(_breakpoint); setter.Set(module, reader); }
private List<SymAttribute> ReadSymAttributes(ISymbolReader reader, ISymbolMethod method, bool haveCSharpCDI) { List<SymAttribute> attrs = new List<SymAttribute>(); foreach (string name in AttributeNamesToSearch()) { // If this attirubte represents C# CDI data, and we were able to expand it, then indicate that // the attribute here is redundant (as a raw view) and shouldn't be included again. if (name == k_cSharpCDIAttrName && haveCSharpCDI) continue; // Note that despite being defined on ISymbolReader instead of ISymbolMethod, custom // attributes are permitted only on method metadata tokens. byte[] attrVal = reader.GetSymAttribute(method.Token, name); if (attrVal != null) { SymAttribute attr = new SymAttribute(); attr.name = name; attr.value = Util.ToHexString(attrVal); attrs.Add(attr); } } return attrs; }
// Write out a reference to the entry point method (if one exists) private string ReadEntryPoint(ISymbolReader reader) { // If there is no entry point token (such as in a dll), this will throw. int tokenVal = reader.UserEntryPoint.GetToken(); if (tokenVal == 0) { // If the Symbol APIs fail when looking for an entry point token, there is no entry point // (eg. probably a dll) return null; } return Util.AsToken(tokenVal); }
// Write all docs, and add to the m_fileMapping list. // Other references to docs will then just refer to this list. private List<Document> ReadDocList(ISymbolReader reader) { List<Document> docs = new List<Document>(); int id = 0; foreach (ISymbolDocument doc in reader.GetDocuments()) { Document docData = new Document(); string url = doc.URL; // Symbol store may give out duplicate documents. We'll fold them here if (m_fileMapping.ContainsKey(url)) { continue; } id++; m_fileMapping.Add(url, id); docData.id = id; docData.url = url; docData.language = doc.Language; docData.languageVendor = doc.LanguageVendor; docData.documentType = doc.DocumentType; docs.Add(docData); } return docs; }
private CSharpCDI ReadCSharpCDI(ISymbolReader reader, ISymbolMethod methodSymbol) { // See if the C# CDI attribute exists byte[] attrVal = reader.GetSymAttribute(methodSymbol.Token, k_cSharpCDIAttrName); if (attrVal == null) return null; // No such attribute try { return CDIReader.ParseCDI(attrVal); } catch (System.FormatException e) { Console.WriteLine("WARNING: Error parsing CSharp CDI for method {0}: {1}", Util.AsToken(methodSymbol.Token.GetToken()), e.Message); return null; } }
private List<Method> ReadAllMethods(ISymbolReader reader) { List<Method> methods = new List<Method>(); foreach (MethodData methodReflection in GetAllMethods(_assemblyPath)) { int token = methodReflection.Token; ISymbolMethod methodSymbol = reader.GetMethod(new SymbolToken(token)); if (methodSymbol != null) { Method methodData = new Method(); methodData.token = Util.AsToken(token); methodData.name = methodReflection.Name; // This localSigMetadataToken information actually comes from the metadata in the assembly because the symbol reading API does not provide it. try { //MethodBody body = methodReflection.GetMethodBody(); //if (body != null) //{ int lSMT = methodReflection.SignatureToken; if (lSMT != 0) { methodData.localSigMetadataToken = Util.AsToken(lSMT); } //} } catch (System.Security.VerificationException) { // Work around a CLR or C# compiler bug with Void& types in signatures // <strip>See DevDiv Bugs 146662</strip> methodData.hasInvalidMethodBody = true; } methodData.sequencePoints = ReadSequencePoints(methodSymbol); methodData.rootScope = ReadScope(methodSymbol.RootScope); // Read symbol attributes, except on ILDB where it isn't supported if (_symFormat != SymbolFormat.ILDB) { if (_expandAttributes) methodData.csharpCDI = ReadCSharpCDI(reader, methodSymbol); methodData.symAttributes = ReadSymAttributes(reader, methodSymbol, methodData.csharpCDI != null); } if (_symFormat == SymbolFormat.PDB) WorkAroundDiasymreaderScopeBug(methodData.rootScope); methods.Add(methodData); } } return methods; }
/// <summary> /// Called when all data regarding an assembly and its types have been delivered /// </summary> public void LeaveAssembly() { _symbolReader = null; }
// Write out a reference to the entry point method (if one exists) private void WriteEntryPoint(ISymbolReader reader) { // If there is no entry point token (such as in a dll), this will throw. SymbolToken token = reader.UserEntryPoint; if (token.GetToken() == 0) { // If the Symbol APIs fail when looking for an entry point token, there is no entry point. m_writer.WriteComment( "There is no entry point token such as a 'Main' method. This module is probably a '.dll'"); return; } ISymbolMethod m = reader.GetMethod(token); Debug.Assert(m != null); // would have thrown by now. // Should not throw past this point m_writer.WriteComment( "This is the token for the 'entry point' method, which is the method that will be called when the assembly is loaded." + " This usually corresponds to 'Main'"); m_writer.WriteStartElement("EntryPoint"); WriteMethod(m); m_writer.WriteEndElement(); }
/// <summary> /// Releases all resources used by the MDbgModule. /// </summary> public void Dispose() { // Our funtion list may hold onto unmanaged SymbolMethod objects, so dispose that too. m_functions.Dispose(); m_functions = null; // Release unmanaged resources. m_symReader = null; m_module = null; m_importer = null; }
/// <summary> /// Read the given PDB file by filename. /// </summary> /// <param name="fileName">The filename and path to the PDB file.</param> public PDBReader(string fileName) { Contract.Requires(fileName != null); _reader = (ISymbolReader)(new QSy.SymbolReader(fileName)); _fileName = fileName; }
/// <summary> /// Updates the symbols for the module. /// </summary> /// <param name="symbolStream">New IStream to use for symbol reading. /// If this is null, unloads the symbols for this module.</param> /// <returns></returns> public bool UpdateSymbols(IStream symbolStream) { if (symbolStream == null) { // Leave m_isSymReaderInitialized so that we don't automatically reload. // MDbgFunction objects cache symbol information. This won't reset that cache. m_isSymReaderInitialized = true; m_symReader = null; return true; } ISymbolReader newSymReader = (SymBinder as ISymbolBinder2).GetReaderFromStream(Importer.RawCOMObject, symbolStream); if (newSymReader == null) return false; m_symReader = newSymReader; // replace symbol reader with the updated one. m_isSymReaderInitialized = true; return true; }
// Dump all of the methods in the given ISymbolReader to the XmlWriter provided in the ctor. private void WriteAllMethods(ISymbolReader reader) { m_writer.WriteComment("This is a list of all methods in the assembly that matches this PDB."); m_writer.WriteComment( "For each method, we provide the sequence tables that map from IL offsets back to source."); m_writer.WriteStartElement("methods"); // Use reflection to enumerate all methods foreach (Type t in m_assembly.GetTypes()) { foreach ( MethodInfo methodReflection in t.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)) { int token = methodReflection.MetadataToken; m_writer.WriteStartElement("method"); { m_writer.WriteAttributeString("name", t.FullName + "." + methodReflection.Name); m_writer.WriteAttributeString("token", Util.AsToken(token)); // This localSigMetadataToken information actually comes from the metadata in the assembly because the symbol reading API does not provide it. if (methodReflection.GetMethodBody() != null) { int lSMT = methodReflection.GetMethodBody().LocalSignatureMetadataToken; if (lSMT != 0) { m_writer.WriteAttributeString("localSigMetadataToken", Util.AsToken(lSMT)); } } ISymbolMethod methodSymbol = reader.GetMethod(new SymbolToken(token)); if (methodSymbol != null) { WriteSequencePoints(methodSymbol); WriteLocals(methodSymbol); ISymbolScope[] children = methodSymbol.RootScope.GetChildren(); if (children.Length != 0) { WriteScopes((ISymbolScope2) children[0]); } } } m_writer.WriteEndElement(); // method } } m_writer.WriteEndElement(); }