public static ComPtr <IDiaSymbol> TryGetSymbols(this DkmModuleInstance moduleInstance) { if (moduleInstance.Module == null) { return(new ComPtr <IDiaSymbol>()); } IDiaSession diaSession; try { diaSession = (IDiaSession)moduleInstance.Module.GetSymbolInterface(typeof(IDiaSession).GUID); } catch (InvalidCastException) { // GetSymbolInterface will throw this if it did locate a symbol provider object, but QueryInterface for the GUID failed with E_NOINTERFACE. // Since this means that we cannot use the symbol provider for anything useful, treat it as absence of symbol information. return(new ComPtr <IDiaSymbol>()); } using (ComPtr.Create(diaSession)) { IDiaEnumSymbols exeSymEnum; diaSession.findChildren(null, SymTagEnum.SymTagExe, null, 0, out exeSymEnum); using (ComPtr.Create(exeSymEnum)) { if (exeSymEnum.count != 1) { return(new ComPtr <IDiaSymbol>()); } return(ComPtr.Create(exeSymEnum.Item(0))); } } }
public static ComPtr <IDiaSymbol> GetTypeSymbol(this IDiaSymbol moduleSym, string name) { IDiaEnumSymbols enumSymbols = null; moduleSym.findChildren(SymTagEnum.SymTagUDT, name, 1, out enumSymbols); using (ComPtr.Create(enumSymbols)) { if (enumSymbols.count > 0) { return(ComPtr.Create(enumSymbols.Item(0))); } } moduleSym.findChildren(SymTagEnum.SymTagTypedef, name, 1, out enumSymbols); using (ComPtr.Create(enumSymbols)) { if (enumSymbols.count > 0) { using (var item = ComPtr.Create(enumSymbols.Item(0))) { return(ComPtr.Create(item.Object.type)); } } Debug.Fail("Type symbol '" + name + "' was not found."); throw new ArgumentException(); } }
public static ComPtr <IDiaSymbol> GetSymbol(this IDiaSymbol symbol, SymTagEnum symTag, string name, Predicate <IDiaSymbol> filter = null) { var result = new ComPtr <IDiaSymbol>(); IDiaEnumSymbols enumSymbols; symbol.findChildren(symTag, name, 1, out enumSymbols); using (ComPtr.Create(enumSymbols)) { int n = enumSymbols.count; if (n == 0) { Debug.Fail("Symbol '" + name + "' was not found."); throw new ArgumentException(); } try { for (int i = 0; i < n; ++i) { using (var item = ComPtr.Create(enumSymbols.Item((uint)i))) { if (filter == null || filter(item.Object)) { if (result.Object == null) { result = item.Detach(); } else { Debug.Fail("Found more than one symbol named '" + name + "' and matching the filter."); throw new ArgumentException(); } } } } } catch { result.Dispose(); throw; } } return(result); }
public static ComPtr <IDiaSymbol>[] GetSymbols(this IDiaSymbol symbol, SymTagEnum symTag, string name) { IDiaEnumSymbols enumSymbols; symbol.findChildren(symTag, name, 1, out enumSymbols); using (ComPtr.Create(enumSymbols)) { int n = enumSymbols.count; var result = new ComPtr <IDiaSymbol> [n]; try { for (int i = 0; i < n; ++i) { result[i] = ComPtr.Create(enumSymbols.Item((uint)i)); } } catch { foreach (var item in result) { item.Dispose(); } throw; } return(result); } }
// For PGO-enabled binaries, their symbol information is unreliable, often in dangerous ways (e.g. FuncDebugStart/End is basically garbage // for split functions, and locals can be messed up), so we do not support Python built with PGO (currently only 2.7.3 and below). private static bool IsModuleCompiledWithPGO(DkmModuleInstance moduleInstance) { using (var moduleSym = moduleInstance.GetSymbols()) { var compSyms = moduleSym.Object.GetSymbols(SymTagEnum.SymTagCompiland, null); try { foreach (var compSym in compSyms) { var blockSyms = compSym.Object.GetSymbols(SymTagEnum.SymTagBlock, null); try { foreach (var blockSym in blockSyms) { using (var parentSym = ComPtr.Create(blockSym.Object.lexicalParent)) { uint blockStart = blockSym.Object.relativeVirtualAddress; uint funcStart = parentSym.Object.relativeVirtualAddress; uint funcEnd = funcStart + (uint)parentSym.Object.length; if (blockStart < funcStart || blockStart >= funcEnd) { return(true); } } } } finally { foreach (var blockSym in blockSyms) { blockSym.Dispose(); } } } } finally { foreach (var funcSym in compSyms) { funcSym.Dispose(); } } } return(false); }
private DkmEvaluationResult GetPythonView(DkmVisualizedExpression visualizedExpression) { var stackFrame = visualizedExpression.StackFrame; var process = stackFrame.Process; var pythonRuntime = process.GetPythonRuntimeInstance(); if (pythonRuntime == null) { return(null); } var home = visualizedExpression.ValueHome as DkmPointerValueHome; if (home == null) { Debug.Fail("PythonViewNativeVisualizer given a visualized expression that has a non-DkmPointerValueHome home."); return(null); } else if (home.Address == 0) { return(null); } var exprEval = process.GetDataItem <ExpressionEvaluator>(); if (exprEval == null) { Debug.Fail("PythonViewNativeVisualizer failed to obtain an instance of ExpressionEvaluator."); return(null); } string cppTypeName = null; var childExpr = visualizedExpression as DkmChildVisualizedExpression; if (childExpr != null) { var evalResult = childExpr.EvaluationResult as DkmSuccessEvaluationResult; cppTypeName = evalResult.Type; } else { object punkTypeSymbol; visualizedExpression.GetSymbolInterface(typeof(IDiaSymbol).GUID, out punkTypeSymbol); using (ComPtr.Create(punkTypeSymbol)) { var typeSymbol = punkTypeSymbol as IDiaSymbol; if (typeSymbol != null) { cppTypeName = typeSymbol.name; } } } PyObject objRef; try { objRef = PyObject.FromAddress(process, home.Address); } catch { return(null); } // TODO: Localization - [Python view] also appears in .natvis file, leave as-is for now var pyEvalResult = new PythonEvaluationResult(objRef, "[Python view]") { Category = DkmEvaluationResultCategory.Property, AccessType = DkmEvaluationResultAccessType.Private }; var inspectionContext = visualizedExpression.InspectionContext; CppExpressionEvaluator cppEval; try { cppEval = new CppExpressionEvaluator(inspectionContext, stackFrame); } catch { return(null); } var pythonContext = DkmInspectionContext.Create(visualizedExpression.InspectionSession, pythonRuntime, stackFrame.Thread, inspectionContext.Timeout, inspectionContext.EvaluationFlags, inspectionContext.FuncEvalFlags, inspectionContext.Radix, DkmLanguage.Create("Python", new DkmCompilerId(Guids.MicrosoftVendorGuid, Guids.PythonLanguageGuid)), null); try { return(exprEval.CreatePyObjectEvaluationResult(pythonContext, stackFrame, null, pyEvalResult, cppEval, cppTypeName, hasCppView: true)); } catch { return(null); } }