Beispiel #1
0
        /// <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
            var reader = SymbolAccess.GetReaderForFile(symFormat, 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);
            assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(assemblyPath);

            fileMapping = new Dictionary <string, int>();

            var symbolData = new SymbolData();

            // Record what input file these symbols are for.
            symbolData.assembly = assemblyPath;

            symbolData.moduleVersion   = assembly.ManifestModule.ModuleVersionId;
            symbolData.entryPointToken = ReadEntryPoint(reader);
            symbolData.sourceFiles     = ReadDocList(reader);

            if (!skipMethods)
            {
                symbolData.methods = ReadAllMethods(reader);
            }

            return(symbolData);
        }
Beispiel #2
0
        public void WritePdb(SymbolData symData)
        {
            m_docWriters = new Dictionary <int, ISymbolDocumentWriter>();

            ImageDebugDirectory debugDirectory;

            byte[] debugInfo = null;
            // Rather than use the emitter here, we are just careful enough to emit pdb metadata that
            // matches what is already in the assembly image.
            object emitter = null;

            // We must be careful to close the writer before updating the debug headers.  The writer has an
            // open file handle on the assembly we want to update.
            m_writer = SymbolAccess.GetWriterForFile(m_symFormat, m_outputAssembly, ref emitter);

            // We don't actually need the emitter in managed code at all, so release the CLR reference on it
            Marshal.FinalReleaseComObject(emitter);

            try
            {
                WriteEntryPoint(symData.entryPointToken);
                WriteFiles(symData.sourceFiles);
                WriteMethods(symData.methods);
                debugInfo = m_writer.GetDebugInfo(out debugDirectory);
            }
            finally
            {
                m_writer.Close();
                ((IDisposable)m_writer).Dispose();
                m_writer = null;
                m_docWriters.Clear();
            }

            UpdatePEDebugHeaders(debugInfo);
        }
Beispiel #3
0
        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>
        }
Beispiel #4
0
        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);
                if (reader == null)
                {
                    ConsoleHelper.WriteLine("Warning: Cannot read symbols for: " + fileName, ConsoleColor.Yellow);
                    try
                    {
                        DateTime asmTime = new FileInfo(fileName).LastWriteTimeUtc;
                        DateTime symTime = new FileInfo(Path.ChangeExtension(fileName, ".pdb")).LastWriteTimeUtc;
                        if (Math.Abs((asmTime - symTime).TotalSeconds) > 10)
                        {
                            ConsoleHelper.WriteLine("  Hint: .pdb file time does not match assembly file time. Either delete or update the symbols file.", ConsoleColor.Yellow);
                        }
                    }
                    catch
                    {
                        // Ignore errors
                    }
                }
                else
                {
                    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>
        }
Beispiel #5
0
        // Maps files to ids.

        /// <summary>
        /// Load the PDB given the parameters at the ctor and spew it out to the XmlWriter specified
        /// at the ctor.
        /// </summary>
        internal void ReadPdbAndWriteToXml()
        {
            // Actually load the files
            // Dynamically discover if there is
            ISymbolReader reader = null;

            // Calling OpenScope on a pdb throws a COMException for CLDB_E_FILE_CORRUPT
            // If they passed a pdb file, we'll try for the exe or dll here in a sec
            if (String.Compare(Path.GetExtension(m_fileName), ".pdb", StringComparison.OrdinalIgnoreCase) != 0)
            {
                reader = SymbolAccess.GetReaderForFile(m_fileName);
            }
            if (reader == null)
            {
                m_fileName = Path.ChangeExtension(m_fileName, ".exe");
                if (File.Exists(m_fileName))
                {
                    reader = SymbolAccess.GetReaderForFile(m_fileName);
                }
            }
            if (reader == null)
            {
                m_fileName = Path.ChangeExtension(m_fileName, ".dll");
                if (File.Exists(m_fileName))
                {
                    reader = SymbolAccess.GetReaderForFile(m_fileName);
                }
            }
            if (reader == null)
            {
                Console.WriteLine("Error: No Symbol Reader could be initialized.");
                return;
            }

            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve;
            m_assembly = Assembly.ReflectionOnlyLoadFrom(m_fileName);

            // Begin writing XML.
            m_writer.WriteStartDocument();
            m_writer.WriteComment("This is an XML file representing the PDB for '" + m_fileName + "'");
            m_writer.WriteStartElement("symbols");


            // Record what input file these symbols are for.
            m_writer.WriteAttributeString("file", m_fileName);

            WriteDocList(reader);
            WriteEntryPoint(reader);
            WriteAllMethods(reader);

            m_writer.WriteEndElement(); // "Symbols";
        }
Beispiel #6
0
    public VariableInfo[] Read(MethodInfo info)
    {
        var il = info.GetMethodBody().LocalVariables.ToArray();

        return(SymbolAccess
               .GetReaderForFile(info.DeclaringType.Assembly.Location)
               .GetMethod(new SymbolToken(info.MetadataToken))
               .RootScope
               .GetInnerScopesRecursive()
               .SelectMany(scope => scope.GetLocals())
               .Select(local =>
                       new VariableInfo(local.AddressField1,
                                        il[local.AddressField1].LocalType,
                                        local.Name))
               .ToArray());
    }
Beispiel #7
0
        private ISymbolReader TryGetSymbolReader(Assembly assembly)
        {
            const int E_PDB_NO_DEBUG_INFO = unchecked ((int)0x806D0014);

            try {
                return(SymbolAccess.GetReaderForFile(assembly.Location));
            }
            catch (COMException ex) {
                if (ex.ErrorCode == E_PDB_NO_DEBUG_INFO)
                {
                    return(null);
                }

                throw;
            }
        }
Beispiel #8
0
        internal Xml2PdbConverter(XmlDocument doc, string OutputAssembly)
        {
            m_doc            = doc;
            m_docWriters     = new Dictionary <int, ISymbolDocumentWriter>();
            m_sequencePoints = new Dictionary <int, List <int>[]>();

            string ext = Path.GetExtension(m_doc.DocumentElement.GetAttribute("file"));

            m_outputAssembly = Path.ChangeExtension(OutputAssembly, ext);

            object emitter = null;

            m_writer = SymbolAccess.GetWriterForFile(m_outputAssembly, ref emitter);
            // Rather than use the emitter here, we are just careful enough to emit pdb metadata that
            // matches what is already in the assembly image.
        }
Beispiel #9
0
            /// <summary>
            /// Creates a <see cref="ISymbolReader"/> for the given <paramref name="assembly"/>.
            /// </summary>
            /// <param name="assembly">The assembly whose reader is needed.</param>
            /// <returns>The <see cref="ISymbolReader"/> instance or <c>null</c> if one cannot be created (e.g. no PDB).</returns>
            private ISymbolReader CreateSymbolReader(Assembly assembly)
            {
                Debug.Assert(assembly != null, "The assembly is required");
                ISymbolReader reader       = null;
                string        assemblyFile = assembly.Location;

                try
                {
                    reader = SymbolAccess.GetReaderForFile(assemblyFile, this._symbolSearchPath);
                }
                catch (System.Runtime.InteropServices.COMException cex)
                {
                    // Experience has shown some large PDB's can exhaust memory and cause COM failures.
                    // When this occurs, we log a warning and continue as if the PDB was not there.
                    if (this._logger != null)
                    {
                        this._logger.LogWarning(string.Format(CultureInfo.CurrentCulture, Resource.Failed_To_Open_PDB, assemblyFile, cex.Message));
                    }
                }

                return(reader);
            }
Beispiel #10
0
        public SourceInfos GetSourceInfos(UInt32 aAddress)
        {
            var xResult = new SourceInfos();

            try
            {
                var xMethod = GetMethod(aAddress);
                if (xMethod != null)
                {
                    var xSymbols      = GetSymbols(xMethod);
                    var xAssemblyFile = mConnection.Get <AssemblyFile>(xMethod.AssemblyFileID);
                    var xSymbolReader = SymbolAccess.GetReaderForFile(xAssemblyFile.Pathname);
                    var xMethodSymbol = xSymbolReader.GetMethod(new SymbolToken(xMethod.MethodToken));

                    int xSeqCount       = xMethodSymbol.SequencePointCount;
                    var xCodeOffsets    = new int[xSeqCount];
                    var xCodeDocuments  = new ISymbolDocument[xSeqCount];
                    var xCodeLines      = new int[xSeqCount];
                    var xCodeColumns    = new int[xSeqCount];
                    var xCodeEndLines   = new int[xSeqCount];
                    var xCodeEndColumns = new int[xSeqCount];
                    xMethodSymbol.GetSequencePoints(xCodeOffsets, xCodeDocuments, xCodeLines, xCodeColumns, xCodeEndLines, xCodeEndColumns);
                    if (xSymbols.Length == 0 && xSeqCount > 0)
                    {
                        var xSourceInfo = new SourceInfo()
                        {
                            SourceFile = xCodeDocuments[0].URL,
                            Line       = xCodeLines[0],
                            LineEnd    = xCodeEndLines[0],
                            Column     = xCodeColumns[0],
                            ColumnEnd  = xCodeEndColumns[0],
                            MethodName = xMethod.LabelCall
                        };
                        xResult.Add(aAddress, xSourceInfo);
                    }
                    else
                    {
                        foreach (var xSymbol in xSymbols)
                        {
                            var xRow = mConnection.Query <Label>(new SQLinq <Label>().Where(i => i.Name == xSymbol.LabelName)).FirstOrDefault();
                            if (xRow != null)
                            {
                                UInt32 xAddress = (UInt32)xRow.Address;
                                // Each address could have mult labels, but this wont matter for SourceInfo, its not tied to label.
                                // So we just ignore duplicate addresses.
                                if (!xResult.ContainsKey(xAddress))
                                {
                                    int xIdx        = SourceInfo.GetIndexClosestSmallerMatch(xCodeOffsets, xSymbol.IlOffset);
                                    var xSourceInfo = new SourceInfo()
                                    {
                                        SourceFile = xCodeDocuments[xIdx].URL,
                                        Line       = xCodeLines[xIdx],
                                        LineEnd    = xCodeEndLines[xIdx],
                                        Column     = xCodeColumns[xIdx],
                                        ColumnEnd  = xCodeEndColumns[xIdx],
                                        MethodName = xMethod.LabelCall
                                    };
                                    xResult.Add(xAddress, xSourceInfo);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
            return(xResult);
        }