Пример #1
0
 public int OpenSession(out IDiaSession session)
 {
     session = null;
     IntPtr _session;
     int hr = S.StdCall<int>(GetVTableMember(8), Punk, out _session);
     GC.KeepAlive(this);
     if (hr != S_OK)
         return hr;
     session = new IDiaSession(_session);
     return hr;
 }
Пример #2
0
        public int OpenSession(out IDiaSession session)
        {
            session = null;
            IntPtr _session;
            int    hr = S.StdCall <int>(GetVTableMember(8), Punk, out _session);

            GC.KeepAlive(this);
            if (hr != S_OK)
            {
                return(hr);
            }
            session = new IDiaSession(_session);
            return(hr);
        }
Пример #3
0
 //
 // Retrieve the source fileName, line number, and column
 //
 private static void TryGetSourceLineInfo(IDiaSession session, int rva, out string fileName, out int lineNumber, out int columnNumber)
 {
     fileName = null;
     lineNumber = 0;
     columnNumber = 0;
     IDiaEnumLineNumbers lineNumbers;
     int hr = session.FindLinesByRVA(rva, 1, out lineNumbers);
     if (hr == S_OK)
     {
         int numLineNumbers;
         hr = lineNumbers.Count(out numLineNumbers);
         if (hr == S_OK && numLineNumbers > 0)
         {
             IDiaLineNumber ln;
             hr = lineNumbers.Item(0, out ln);
             if (hr == S_OK)
             {
                 IDiaSourceFile sourceFile;
                 hr = ln.SourceFile(out sourceFile);
                 if (hr == S_OK)
                 {
                     hr = sourceFile.FileName(out fileName);
                     if (hr == S_OK)
                     {
                         hr = ln.LineNumber(out lineNumber);
                         if (hr == S_OK)
                         {
                             hr = ln.ColumnNumber(out columnNumber);
                         }
                     }
                 }
             }
         }
     }
 }
Пример #4
0
        private static String ToTypeStringWorker(this IDiaSymbol parameterType, IDiaSession session, int recursionLevel, out bool isValueTypeOrByRef)
        {
            int hr;
            isValueTypeOrByRef = false;

            // Block runaway recursions.
            if (recursionLevel++ > 10)
                return "?";

            SymTagEnum symTag;
            hr = parameterType.GetSymTag(out symTag);
            if (hr != S_OK)
                return "?";
            if (symTag == SymTagEnum.SymTagPointerType)
            {
                bool isReference;
                hr = parameterType.GetReference(out isReference);
                if (hr != S_OK)
                    return "?";

                if (isReference)
                {
                    // An isReference pointer can mean one of two things:
                    //   1. ELEMENT_TYPE_BYREF
                    //   2. An indication that the UDT that follows is actually a class, not a struct.
                    //
                    isValueTypeOrByRef = true;
                    IDiaSymbol targetType;
                    hr = parameterType.GetType(out targetType);
                    if (hr != S_OK)
                        return "?";
                    bool targetIsValueTypeOrByRef;
                    String targetTypeString = targetType.ToTypeStringWorker(session, recursionLevel, out targetIsValueTypeOrByRef);
                    if (targetIsValueTypeOrByRef)
                        return targetTypeString + "&";
                    else
                        return targetTypeString;
                }
                else
                {
                    // A non-isReference pointer means an ELEMENT_TYPE_PTR
                    IDiaSymbol targetType;
                    hr = parameterType.GetType(out targetType);
                    if (hr != S_OK)
                        return "?";
                    bool ignore;
                    return targetType.ToTypeStringWorker(session, recursionLevel, out ignore) + "*";
                }
            }
            else if (symTag == SymTagEnum.SymTagArrayType)
            {
                // Note: We don't actually hit this case in NUTC-generated PDB's as NUTC emits arrays as if they were UDT's with square brackets in the name.
                // But just in case NUTC ever changes its PDB emission, we'll print out the most obvious interpretation and hope we're right.
                IDiaSymbol elementType;
                hr = parameterType.GetType(out elementType);
                if (hr != S_OK)
                    return "?";
                bool ignore;
                return elementType.ToTypeStringWorker(session, recursionLevel, out ignore) + "[]";
            }
            else if (symTag == SymTagEnum.SymTagUDT || symTag == SymTagEnum.SymTagEnum)
            {
                // Need to figure out whether this is a value type as our recursive caller needs to know whether the "byref pointer" that wrapped this
                // is a true managed byref or just the "byref pointer" that wraps all non-valuetypes.
                if (symTag == SymTagEnum.SymTagEnum)
                {
                    isValueTypeOrByRef = true;
                }
                else
                {
                    IDiaEnumSymbols baseClasses;
                    hr = session.FindChildren(parameterType, SymTagEnum.SymTagBaseClass, null, 0, out baseClasses);
                    if (hr != S_OK)
                        return "?";
                    int count;
                    hr = baseClasses.Count(out count);
                    if (hr != S_OK)
                        return "?";
                    for (int i = 0; i < count; i++)
                    {
                        IDiaSymbol baseClass;
                        if (S_OK == baseClasses.Item(i, out baseClass))
                        {
                            String baseClassName;
                            if (S_OK == baseClass.GetName(out baseClassName))
                            {
                                if (baseClassName == "System::ValueType")
                                    isValueTypeOrByRef = true;
                            }
                        }
                    }
                }

                String name;
                hr = parameterType.GetName(out name);
                if (hr != S_OK)
                    return "?";
                return name.RemoveNamespaces().Demanglify();
            }
            else if (symTag == SymTagEnum.SymTagBaseType)
            {
                // Certain "primitive" types are encoded specially.
                BasicType basicType;
                hr = parameterType.GetBaseType(out basicType);
                if (hr != S_OK)
                    return "?";
                long length;
                hr = parameterType.GetLength(out length);
                if (hr != S_OK)
                    return "?";
                return ConvertBasicTypeToTypeString(basicType, length, out isValueTypeOrByRef);
            }
            else
            {
                return "?";
            }
        }
Пример #5
0
 private static String ToTypeString(this IDiaSymbol parameterType, IDiaSession session)
 {
     bool ignore;
     return parameterType.ToTypeStringWorker(session, 0, out ignore);
 }
Пример #6
0
 //
 // Generate the " in <filename>:line <line#>" section.
 //
 private static String CreateSourceInfoString(IDiaSession session, int rva)
 {
     StringBuilder sb = new StringBuilder();
     string fileName;
     int lineNumber, columnNumber;
     TryGetSourceLineInfo(session, rva, out fileName, out lineNumber, out columnNumber);
     if(!string.IsNullOrEmpty(fileName))
     {
         sb.Append(" in ").Append(fileName);
         if(lineNumber >= 0)
         {
             sb.Append(":line ").Append(lineNumber);
         }
     }
     return sb.ToString();
 }
Пример #7
0
        //
        // Create the method parameter list.
        //
        private static String CreateParameterListString(IDiaSession session, IDiaSymbol symbol)
        {
            StringBuilder sb = new StringBuilder("(");

            // find the parameters
            IDiaEnumSymbols dataSymbols;
            int hr = session.FindChildren(symbol, SymTagEnum.SymTagData, null, NameSearchOptions.nsNone, out dataSymbols);
            if (hr == S_OK)
            {
                int count;
                hr = dataSymbols.Count(out count);
                if (hr == S_OK)
                {
                    for (int i = 0, iParam = 0; i < count; i++)
                    {
                        IDiaSymbol dataSym;
                        hr = dataSymbols.Item(i, out dataSym);
                        if (hr != S_OK)
                            continue;

                        DataKind dataKind;
                        hr = dataSym.GetDataKind(out dataKind);
                        if (hr != S_OK || dataKind != DataKind.DataIsParam)
                            continue;

                        string paramName;
                        hr = dataSym.GetName(out paramName);
                        if (hr != S_OK)
                        {
                            continue;
                        }

                        //this approximates the way C# displays methods by not including these hidden arguments
                        if (paramName == "InstParam" || paramName == "this")
                        {
                            continue;
                        }

                        IDiaSymbol parameterType;
                        hr = dataSym.GetType(out parameterType);
                        if (hr != S_OK)
                        {
                            continue;
                        }

                        if (iParam++ != 0)
                            sb.Append(", ");

                        sb.Append(parameterType.ToTypeString(session));
                        sb.Append(' ');
                        sb.Append(paramName);
                    }
                }
            }
            sb.Append(')');
            return sb.ToString();
        }
Пример #8
0
        /// <summary>
        /// Locate and lazily load debug info for the native app module overlapping given
        /// virtual address.
        /// </summary>
        /// <param name="ip">Instruction pointer address (code address for the lookup)</param>
        /// <param name="rva">Output VA relative to module base</param>
        private static IDiaSession GetDiaSession(IntPtr ip, out int rva)
        {
            if (ip == IntPtr.Zero)
            {
                rva = -1;
                return null;
            }

            IntPtr moduleBase = RuntimeAugments.GetModuleFromPointer(ip);
            if (moduleBase == IntPtr.Zero)
            {
                rva = -1;
                return null;
            }

            rva = (int)(ip.ToInt64() - moduleBase.ToInt64());

            if (s_loadedModules == null)
            {
                // Lazily create the parallel arrays s_loadedModules and s_perModuleDebugInfo
                int moduleCount = RuntimeAugments.GetLoadedModules(null);

                s_loadedModules = new IntPtr[moduleCount];
                s_perModuleDebugInfo = new IDiaSession[moduleCount];

                // Actually read the module addresses into the array
                RuntimeAugments.GetLoadedModules(s_loadedModules);
            }

            // Locate module index based on base address
            int moduleIndex = s_loadedModules.Length;
            do
            {
                if (--moduleIndex < 0)
                {
                    return null;
                }
            }
            while(s_loadedModules[moduleIndex] != moduleBase);

            IDiaSession diaSession = s_perModuleDebugInfo[moduleIndex];
            if (diaSession != null)
            {
                return diaSession;
            }
            
            string modulePath = RuntimeAugments.TryGetFullPathToApplicationModule(moduleBase);
            if (modulePath == null)
            {
                return null;
            }

            int indexOfLastDot = modulePath.LastIndexOf('.');
            if (indexOfLastDot == -1)
            {
                return null;
            }

            IDiaDataSource diaDataSource = GetDiaDataSource();
            if (diaDataSource == null)
            {
                return null;
            }

            // Look for .pdb next to .exe / dll - if it's not there, bail.
            String pdbPath = modulePath.Substring(0, indexOfLastDot) + ".pdb";
            int hr = diaDataSource.LoadDataFromPdb(pdbPath);
            if (hr != S_OK)
            {
                return null;
            }

            hr = diaDataSource.OpenSession(out diaSession);
            if (hr != S_OK)
            {
                return null;
            }

            s_perModuleDebugInfo[moduleIndex] = diaSession;
            return diaSession;
        }