예제 #1
0
        /// <summary>
        /// Obtain the original source code file and line number for the given
        /// IL offset in a method identified by a unique metadata token.
        /// </summary>
        /// <param name="methodMetadataToken"></param>
        /// <param name="ilOffset"></param>
        /// <returns></returns>
        /// <remarks>
        /// Metadata token is stored in the PDB file for each method. Additionally
        /// it can always be retrieved from MethodInfo via reflection. Exception
        /// report saves a meatdata token for each method in the stack trace.
        /// </remarks>
        public SourceLocation GetSourceLoc(int methodMetadataToken, int ilOffset)
        {
            IDiaSymbol symMethod;

            _session.findSymbolByToken((uint)methodMetadataToken, SymTagEnum.SymTagFunction, out symMethod);

            var rvaMethod = symMethod.relativeVirtualAddress;

            rvaMethod += (uint)ilOffset;

            IDiaEnumLineNumbers lineNumbers;

            _session.findLinesByRVA(rvaMethod, 1, out lineNumbers);

            foreach (IDiaLineNumber ln in lineNumbers)
            {
                var sourceFile = ln.sourceFile;
                return(new SourceLocation()
                {
                    LineNumber = ln.lineNumber, SourceFile = (sourceFile == null) ? null : sourceFile.fileName
                });
            }

            return(null);
        }
예제 #2
0
        /// <summary>
        /// Gets the source file name and line for the specified stack frame.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <param name="sourceFileName">Name of the source file.</param>
        /// <param name="sourceFileLine">The source file line.</param>
        /// <param name="displacement">The displacement.</param>
        /// <exception cref="System.Exception">Address not found</exception>
        /// <exception cref="Exception">Address not found</exception>
        public void GetSourceFileNameAndLine(uint address, out string sourceFileName, out uint sourceFileLine, out ulong displacement)
        {
            IDiaSymbol          function    = session.findSymbolByRVA(address, SymTagEnum.Function);
            IDiaEnumLineNumbers lineNumbers = session.findLinesByRVA(address, (uint)function.length);

            foreach (IDiaLineNumber lineNumber in lineNumbers.Enum())
            {
                if (address >= lineNumber.relativeVirtualAddress)
                {
                    sourceFileName = lineNumber.sourceFile.fileName;
                    sourceFileLine = lineNumber.lineNumber;
                    displacement   = address - lineNumber.relativeVirtualAddress;
                    return;
                }
            }

            throw new Exception("Address not found");
        }
예제 #3
0
        public static string GetMethodName(IDiaSession pdbSession, uint rva)
        {
            IDiaSymbol funcSym;

            pdbSession.findSymbolByRVA(rva, SymTagEnum.SymTagFunction, out funcSym);
            if (funcSym == null)
            {
                pdbSession.findSymbolByRVA(rva, SymTagEnum.SymTagPublicSymbol, out funcSym);
            }

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

            StringBuilder methodNameStr = new StringBuilder();

            // Append the method-name
            methodNameStr.Append(funcSym.GetUndecoratedNameEx(UndName.DebuggerInternal));

            // Append the offset of current instruction inside method
            methodNameStr.Append("+0x");
            methodNameStr.Append(Convert.ToString(rva - funcSym.GetRelativeVirtualAddress(), 16));

            // Append the source line
            IDiaEnumLineNumbers lines      = null;
            IDiaSourceFile      sourceFile = null;

            pdbSession.findLinesByRVA(rva, 1, out lines);
            int i;

            if (lines != null && lines.count == 1)
            {
                IDiaLineNumber line = lines.Item(0);
                if (line != null)
                {
                    sourceFile = line.SourceFile;
                    methodNameStr.Append(" (");
                    methodNameStr.Append(sourceFile.FileName);
                    methodNameStr.Append(", line ");
                    methodNameStr.Append(line.LineNumber);
                    methodNameStr.Append(")");

                    i = Marshal.ReleaseComObject(line);
                    if (i != 0)
                    {
                        Console.WriteLine("RefCount(funcSym) == {0}", i);
                    }
                }
            }
            i = Marshal.ReleaseComObject(funcSym);
            if (i != 0)
            {
                Console.WriteLine("RefCount(funcSym) == {0}", i);
            }
            if (lines != null)
            {
                if (sourceFile != null)
                {
                    i = Marshal.ReleaseComObject(sourceFile);
                    if (i != 0)
                    {
                        Console.WriteLine("RefCount(sourceFile) == {0}", i);
                    }
                }
                // line?
                i = Marshal.ReleaseComObject(lines);
                if (i != 0)
                {
                    Console.WriteLine("RefCount(lines) == {0}", i);
                }
            }

            //return funcSym.GetName();
            return(methodNameStr.ToString());
        }