Beispiel #1
0
 /// <summary>
 /// Converts <see cref="IDiaEnumLineNumbers"/> container to <see cref="IEnumerable{IDiaLineNumber}"/>.
 /// </summary>
 /// <param name="container">The container.</param>
 public static IEnumerable <IDiaLineNumber> Enum(this IDiaEnumLineNumbers container)
 {
     foreach (IDiaLineNumber lineNumber in container)
     {
         yield return(lineNumber);
     }
 }
Beispiel #2
0
        private DiaNavigationData GetSymbolNavigationData(IDiaSymbol symbol)
        {
            ValidateArg.NotNull(symbol, "symbol");

            DiaNavigationData navigationData = new DiaNavigationData(null, int.MaxValue, int.MinValue);

            IDiaEnumLineNumbers lines = null;

            try
            {
                this.session.findLinesByAddr(symbol.addressSection, symbol.addressOffset, (uint)symbol.length, out lines);

                uint           celt;
                IDiaLineNumber lineNumber;

                while (true)
                {
                    lines.Next(1, out lineNumber, out celt);

                    if (celt != 1)
                    {
                        break;
                    }

                    IDiaSourceFile sourceFile = null;
                    try
                    {
                        sourceFile = lineNumber.sourceFile;

                        // The magic hex constant below works around weird data reported from GetSequencePoints.
                        // The constant comes from ILDASM's source code, which performs essentially the same test.
                        const uint Magic = 0xFEEFEE;
                        if (lineNumber.lineNumber >= Magic || lineNumber.lineNumberEnd >= Magic)
                        {
                            continue;
                        }

                        navigationData.FileName      = sourceFile.fileName;
                        navigationData.MinLineNumber = Math.Min(navigationData.MinLineNumber, (int)lineNumber.lineNumber);
                        navigationData.MaxLineNumber = Math.Max(navigationData.MaxLineNumber, (int)lineNumber.lineNumberEnd);
                    }
                    finally
                    {
                        ReleaseComObject(ref sourceFile);
                        ReleaseComObject(ref lineNumber);
                    }
                }
            }
            finally
            {
                ReleaseComObject(ref lines);
            }

            return(navigationData);
        }
Beispiel #3
0
        /// <summary>
        /// Converts <see cref="IDiaEnumLineNumbers"/> container to <see cref="IEnumerable{IDiaLineNumber}"/>.
        /// </summary>
        /// <param name="container">The container.</param>
        public static IEnumerable <IDiaLineNumber> Enum(this IDiaEnumLineNumbers container)
        {
            IDiaLineNumber[] tempLineNumbers = new IDiaLineNumber[1];
            container.Reset();
            while (true)
            {
                uint count;

                container.Next((uint)tempLineNumbers.Length, tempLineNumbers, out count);
                if (count == 0)
                {
                    break;
                }
                yield return(tempLineNumbers[0]);
            }
        }
Beispiel #4
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");
        }
        private SourceFileLocation ToSourceFileLocation(NativeSourceFileLocation nativeSymbol)
        {
            IDiaEnumLineNumbers lineNumbers = GetLineNumbers(nativeSymbol.AddressSection, nativeSymbol.AddressOffset, nativeSymbol.Length);

            if (lineNumbers.count <= 0)
            {
                _logger.LogWarning("Failed to locate line number for " + nativeSymbol);
                return(new SourceFileLocation(_binary, "", 0));
            }

            SourceFileLocation result = null;

            foreach (IDiaLineNumber lineNumber in lineNumbers)
            {
                if (result == null)
                {
                    result = new SourceFileLocation(
                        nativeSymbol.Symbol, lineNumber.sourceFile.fileName,
                        lineNumber.lineNumber);
                    // do not break to make sure all lineNumbers are enumerated - not sure if this is necessary
                }
            }
            return(result);
        }
        private SourceFileLocation ToSourceFileLocation(NativeSourceFileLocation nativeSymbol)
        {
            IDiaEnumLineNumbers lineNumbers = GetLineNumbers(nativeSymbol.AddressSection, nativeSymbol.AddressOffset, nativeSymbol.Length);

            if (lineNumbers.count > 0)
            {
                SourceFileLocation result = null;
                foreach (IDiaLineNumber lineNumber in lineNumbers)
                {
                    if (result == null)
                    {
                        result = new SourceFileLocation(
                            nativeSymbol.Symbol, lineNumber.sourceFile.fileName,
                            lineNumber.lineNumber);
                    }
                }
                return(result);
            }
            else
            {
                ErrorMessages.Add("Failed to locate line number for " + nativeSymbol);
                return(new SourceFileLocation(Binary, "", 0));
            }
        }
Beispiel #7
0
        private DiaNavigationData GetSymbolNavigationData(IDiaSymbol symbol)
        {
            ValidateArg.NotNull(symbol, "symbol");

            DiaNavigationData navigationData = new DiaNavigationData(null, int.MaxValue, int.MinValue);

            IDiaEnumLineNumbers lines = null;

            try
            {
                // Get the address section
                if (HResult.Failed(symbol.GetAddressSection(out uint section)))
                {
                    return(navigationData);
                }

                // Get the address offset
                if (HResult.Failed(symbol.GetAddressOffset(out uint offset)))
                {
                    return(navigationData);
                }

                // Get the length of the symbol
                if (HResult.Failed(symbol.GetLength(out long length)))
                {
                    return(navigationData);
                }

                this.session.FindLinesByAddress(section, offset, (uint)length, out lines);

                while (true)
                {
                    lines.GetNext(1, out IDiaLineNumber lineNumber, out uint celt);

                    if (celt != 1)
                    {
                        break;
                    }

                    IDiaSourceFile sourceFile = null;
                    try
                    {
                        lineNumber.GetSourceFile(out sourceFile);

                        // Get startline
                        lineNumber.GetLineNumber(out uint startLine);

                        // Get endline
                        lineNumber.GetLineNumberEnd(out uint endLine);

                        // The magic hex constant below works around weird data reported from GetSequencePoints.
                        // The constant comes from ILDASM's source code, which performs essentially the same test.
                        const uint Magic = 0xFEEFEE;
                        if (startLine >= Magic || endLine >= Magic)
                        {
                            continue;
                        }

                        sourceFile.GetFilename(out var srcFileName);

                        navigationData.FileName      = srcFileName;
                        navigationData.MinLineNumber = Math.Min(navigationData.MinLineNumber, (int)startLine);
                        navigationData.MaxLineNumber = Math.Max(navigationData.MaxLineNumber, (int)endLine);
                    }
                    finally
                    {
                        ReleaseComObject(ref sourceFile);
                        ReleaseComObject(ref lineNumber);
                    }
                }
            }
            finally
            {
                ReleaseComObject(ref lines);
            }

            return(navigationData);
        }
 public void findLinesByAddr(uint seg, uint offset, uint length, out IDiaEnumLineNumbers ppResult)
 {
     ppResult = null;
     _diaSession140?.findLinesByAddr(seg, offset, length, out ppResult);
     _diaSession110?.findLinesByAddr(seg, offset, length, out ppResult);
 }
 public void findLinesByAddr(uint seg, uint offset, uint length, out IDiaEnumLineNumbers ppResult)
 {
     ppResult = null;
     _diaSession140?.findLinesByAddr(seg, offset, length, out ppResult);
     _diaSession110?.findLinesByAddr(seg, offset, length, out ppResult);
 }
Beispiel #10
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());
        }