internal string ExecuteExpression(string expression, DkmStackContext stackContext, DkmStackWalkFrame input, bool allowZero) { var compilerId = new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp); var language = DkmLanguage.Create("C++", compilerId); var languageExpression = DkmLanguageExpression.Create(language, DkmEvaluationFlags.None, expression, null); var inspectionContext = DkmInspectionContext.Create(stackContext.InspectionSession, input.RuntimeInstance, stackContext.Thread, 200, DkmEvaluationFlags.None, DkmFuncEvalFlags.None, 10, language, null); var workList = DkmWorkList.Create(null); string resultText = null; inspectionContext.EvaluateExpression(workList, languageExpression, input, res => { if (res.ErrorCode == 0) { var result = res.ResultObject as DkmSuccessEvaluationResult; if (result != null && result.TagValue == DkmEvaluationResult.Tag.SuccessResult && (allowZero || result.Address.Value != 0)) { resultText = result.Value; } res.ResultObject.Close(); } }); workList.Execute(); return(resultText); }
internal static DkmEvaluationResult ExecuteRawExpression(string expression, DkmInspectionSession inspectionSession, DkmThread thread, DkmStackWalkFrame input, DkmRuntimeInstance runtimeInstance, DkmEvaluationFlags flags) { var compilerId = new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp); var language = DkmLanguage.Create("C++", compilerId); var languageExpression = DkmLanguageExpression.Create(language, DkmEvaluationFlags.None, expression, null); var inspectionContext = DkmInspectionContext.Create(inspectionSession, runtimeInstance, thread, 200, flags, DkmFuncEvalFlags.None, 10, language, null, null, DkmCompiledVisualizationDataPriority.None, null, workerConnection); var workList = DkmWorkList.Create(null); try { DkmEvaluationResult result = null; inspectionContext.EvaluateExpression(workList, languageExpression, input, res => { if (res.ErrorCode == 0) { result = res.ResultObject; } }); workList.Execute(); return(result); } catch (OperationCanceledException) { return(null); } }
private void TestNativeView(bool enableNativeDebugging) { var source = @"class C { }"; using (new EnsureEnglishUICulture()) { var assembly = GetAssembly(source); var assemblies = ReflectionUtilities.GetMscorlibAndSystemCore(assembly); using (ReflectionUtilities.LoadAssemblies(assemblies)) { var runtime = new DkmClrRuntimeInstance( assemblies, enableNativeDebugging: enableNativeDebugging ); var inspectionContext = CreateDkmInspectionContext(runtimeInstance: runtime); var type = assembly.GetType("C"); var value = CreateDkmClrValue( value: type.Instantiate(), type: runtime.GetType((TypeImpl)type), nativeComPointer: 0xfe ); var evalResult = FormatResult("o", value, inspectionContext: inspectionContext); Verify( evalResult, EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.Expandable) ); var children = GetChildren(evalResult, inspectionContext); if (enableNativeDebugging) { string pointerString = $"(IUnknown*){PointerToString(new IntPtr(0xfe))}"; DkmLanguage language = new DkmLanguage( new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp) ); Verify( children, EvalIntermediateResult( "Native View", "{C++}" + pointerString, pointerString, language ) ); } else { Verify( children, EvalFailedResult( "Native View", "To inspect the native object, enable native code debugging." ) ); } } } }
internal static string ExecuteExpression(string expression, DkmInspectionSession inspectionSession, DkmThread thread, DkmStackWalkFrame input, DkmEvaluationFlags flags, bool allowZero, out ulong address) { if (Log.instance != null) { Log.instance.Verbose($"ExecuteExpression begin evaluation of '{expression}'"); } var compilerId = new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp); var language = DkmLanguage.Create("C++", compilerId); var languageExpression = DkmLanguageExpression.Create(language, DkmEvaluationFlags.None, expression, null); var inspectionContext = DkmInspectionContext.Create(inspectionSession, input.RuntimeInstance, thread, 200, flags, DkmFuncEvalFlags.None, 10, language, null, null, DkmCompiledVisualizationDataPriority.None, null, workerConnection); var workList = DkmWorkList.Create(null); try { string resultText = null; ulong resultAddress = 0; inspectionContext.EvaluateExpression(workList, languageExpression, input, res => { if (res.ErrorCode == 0) { var result = res.ResultObject as DkmSuccessEvaluationResult; if (result != null && result.TagValue == DkmEvaluationResult.Tag.SuccessResult && (allowZero || result.Address.Value != 0)) { resultText = result.Value; resultAddress = result.Address.Value; } res.ResultObject.Close(); } }); workList.Execute(); if (Log.instance != null) { Log.instance.Verbose($"ExecuteExpression completed"); } address = resultAddress; return(resultText); } catch (OperationCanceledException) { address = 0; return(null); } }
internal static DkmIntermediateEvaluationResult EvalIntermediateResult( string name, string fullName, string expression, DkmLanguage language) { return(DkmIntermediateEvaluationResult.Create( InspectionContext: null, StackFrame: null, Name: name, FullName: fullName, Expression: expression, IntermediateLanguage: language, TargetRuntime: null, DataItem: null)); }
public static unsafe PyFrameObject TryCreate(DkmStackWalkFrame frame) { var process = frame.Process; if (frame.InstructionAddress == null) { return(null); } if (frame.RuntimeInstance.Id.RuntimeType != Guids.PythonRuntimeTypeGuid && !IsInEvalFrame(frame)) { return(null); } var cppLanguage = DkmLanguage.Create("C++", new DkmCompilerId(Guids.MicrosoftVendorGuid, Guids.CppLanguageGuid)); var inspectionSession = DkmInspectionSession.Create(process, null); var inspectionContext = DkmInspectionContext.Create(inspectionSession, process.GetNativeRuntimeInstance(), frame.Thread, 0, DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, 10, cppLanguage, null); CppExpressionEvaluator cppEval; try { cppEval = new CppExpressionEvaluator(inspectionContext, frame); } catch (ArgumentException) { Debug.Fail("Failed to create C++ expression evaluator while obtaining PyFrameObject from a native frame."); return(null); } ulong framePtr; try { framePtr = cppEval.EvaluateUInt64("f"); } catch (CppEvaluationException) { Debug.Fail("Failed to evaluate the 'f' parameter to PyEval_EvalFrameEx while obtaining PyFrameObject from a native frame."); return(null); } return(new PyFrameObject(frame.Process, framePtr)); }
DkmCustomMessage IDkmCustomMessageForwardReceiver.SendLower(DkmCustomMessage customMessage) { var process = customMessage.Process; var processData = DebugHelpers.GetOrCreateDataItem <LuaRemoteProcessData>(process); if (customMessage.MessageCode == MessageToRemote.createRuntime) { if (processData.language == null) { processData.compilerId = new DkmCompilerId(Guids.luaCompilerGuid, Guids.luaLanguageGuid); processData.language = DkmLanguage.Create("Lua", processData.compilerId); } if (processData.runtimeInstance == null) { DkmRuntimeInstanceId runtimeId = new DkmRuntimeInstanceId(Guids.luaRuntimeGuid, 0); processData.runtimeInstance = DkmCustomRuntimeInstance.Create(process, runtimeId, null); } if (processData.module == null) { DkmModuleId moduleId = new DkmModuleId(Guid.NewGuid(), Guids.luaSymbolProviderGuid); processData.module = DkmModule.Create(moduleId, "lua.vm.code", processData.compilerId, process.Connection, null); } if (processData.moduleInstance == null) { DkmDynamicSymbolFileId symbolFileId = DkmDynamicSymbolFileId.Create(Guids.luaSymbolProviderGuid); processData.moduleInstance = DkmCustomModuleInstance.Create("lua_vm", "lua.vm.code", 0, processData.runtimeInstance, null, symbolFileId, DkmModuleFlags.None, DkmModuleMemoryLayout.Unknown, 0, 1, 0, "Lua vm code", false, null, null, null); processData.moduleInstance.SetModule(processData.module, true); // Can use reload? } } else if (customMessage.MessageCode == MessageToRemote.luaHelperDataLocations) { var data = new HelperLocationsMessage(); data.ReadFrom(customMessage.Parameter1 as byte[]); processData.locations = data; } else if (customMessage.MessageCode == MessageToRemote.pauseBreakpoints) { processData.pauseBreakpoints = true; } else if (customMessage.MessageCode == MessageToRemote.resumeBreakpoints) { processData.pauseBreakpoints = false; } else if (customMessage.MessageCode == MessageToRemote.luaVersionInfo) { processData.luaVersion = (customMessage.Parameter1 as int?).GetValueOrDefault(0); LuaHelpers.luaVersion = processData.luaVersion; } else if (customMessage.MessageCode == MessageToRemote.registerLuaState) { var data = new RegisterStateMessage(); data.ReadFrom(customMessage.Parameter1 as byte[]); Debug.Assert(processData.knownStates.ContainsKey(data.stateAddress) == false); if (processData.knownStates.ContainsKey(data.stateAddress)) { Debug.WriteLine("IDkmCustomMessageForwardReceiver.SendLower() Duplicate Lua state registration, destruction was probably missed!"); } else { processData.knownStates.Add(data.stateAddress, data); if (processData.hooksEnabled) { SetupHooks(process, processData); } } } else if (customMessage.MessageCode == MessageToRemote.unregisterLuaState) { var data = new UnregisterStateMessage(); data.ReadFrom(customMessage.Parameter1 as byte[]); // Registration is called only for states that can be hooked, unregistration is always called if (processData.knownStates.ContainsKey(data.stateAddress)) { processData.knownStates.Remove(data.stateAddress); } } return(null); }
private static DkmEvaluationResult CreateEvaluationResult( DkmInspectionContext inspectionContext, DkmClrValue value, string name, string typeName, string display, EvalResultDataItem dataItem) { if (value.IsError()) { // Evaluation failed return(DkmFailedEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: name, FullName: dataItem.FullName, ErrorMessage: display, Flags: dataItem.Flags, Type: typeName, DataItem: dataItem)); } else if (dataItem.Kind == ExpansionKind.NativeView) { // For Native View, create a DkmIntermediateEvaluationResult. This will allow the C++ EE // to take over expansion. DkmProcess process = inspectionContext.RuntimeInstance.Process; DkmLanguage cpp = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp)); return(DkmIntermediateEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: Resources.NativeView, FullName: dataItem.FullName, Expression: dataItem.Name, IntermediateLanguage: cpp, TargetRuntime: process.GetNativeRuntimeInstance(), DataItem: dataItem)); } else { ReadOnlyCollection <DkmCustomUIVisualizerInfo> customUIVisualizers = null; if (!value.IsNull) { DkmCustomUIVisualizerInfo[] customUIVisualizerInfo = value.Type.GetDebuggerCustomUIVisualizerInfo(); if (customUIVisualizerInfo != null) { customUIVisualizers = new ReadOnlyCollection <DkmCustomUIVisualizerInfo>(customUIVisualizerInfo); } } // If the EvalResultData item doesn't specify a particular category, we'll just propagate DkmClrValue.Category, // which typically appears to be set to the default value ("Other"). var category = (dataItem.Category != DkmEvaluationResultCategory.Other) ? dataItem.Category : value.Category; // Valid value return(DkmSuccessEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: name, FullName: dataItem.FullName, Flags: dataItem.Flags, Value: display, EditableValue: dataItem.EditableValue, Type: typeName, Category: category, Access: value.Access, StorageType: value.StorageType, TypeModifierFlags: value.TypeModifierFlags, Address: value.Address, CustomUIVisualizers: customUIVisualizers, ExternalModules: null, DataItem: dataItem)); } }
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); } }
void IDkmProcessExecutionNotification.OnProcessPause(DkmProcess process, DkmProcessExecutionCounters processCounters) { try { ulong?moduleBaseOpt = DebugHelpers.ReadPointerVariable(process, "nullcModuleStartAddress"); // Check if nullc is available if (moduleBaseOpt == null) { return; } var processData = DebugHelpers.GetOrCreateDataItem <NullcRemoteProcessDataItem>(process); if (processData.language == null) { processData.compilerId = new DkmCompilerId(DebugHelpers.NullcCompilerGuid, DebugHelpers.NullcLanguageGuid); processData.language = DkmLanguage.Create("nullc", processData.compilerId); } // Create VM runtime and module if (processData.vmRuntimeInstance == null) { DkmRuntimeInstanceId runtimeId = new DkmRuntimeInstanceId(DebugHelpers.NullcVmRuntimeGuid, 0); processData.vmRuntimeInstance = DkmCustomRuntimeInstance.Create(process, runtimeId, null); } if (processData.vmModule == null) { DkmModuleId moduleId = new DkmModuleId(Guid.NewGuid(), DebugHelpers.NullcSymbolProviderGuid); processData.vmModule = DkmModule.Create(moduleId, "nullc.vm.code", processData.compilerId, process.Connection, null); } if (processData.vmModuleInstance == null) { DkmDynamicSymbolFileId symbolFileId = DkmDynamicSymbolFileId.Create(DebugHelpers.NullcSymbolProviderGuid); processData.vmModuleInstance = DkmCustomModuleInstance.Create("nullc_vm", "nullc.vm.code", 0, processData.vmRuntimeInstance, null, symbolFileId, DkmModuleFlags.None, DkmModuleMemoryLayout.Unknown, 0, 1, 0, "nullc vm code", false, null, null, null); processData.vmModuleInstance.SetModule(processData.vmModule, true); // Can use reload? } ulong moduleBase = moduleBaseOpt.GetValueOrDefault(0); uint moduleSize = (uint)(DebugHelpers.ReadPointerVariable(process, "nullcModuleEndAddress").GetValueOrDefault(0) - moduleBase); // Create JiT runtime and module if (moduleBase != 0 && moduleSize != 0) { if (processData.runtimeInstance == null && processData.nativeRuntimeInstance == null) { DkmRuntimeInstanceId runtimeId = new DkmRuntimeInstanceId(DebugHelpers.NullcRuntimeGuid, 0); if (DebugHelpers.useNativeInterfaces) { processData.nativeRuntimeInstance = DebugHelpers.useDefaultRuntimeInstance ? process.GetNativeRuntimeInstance() : DkmNativeRuntimeInstance.Create(process, runtimeId, DkmRuntimeCapabilities.None, process.GetNativeRuntimeInstance(), null); } else { processData.runtimeInstance = DkmCustomRuntimeInstance.Create(process, runtimeId, null); } } if (processData.module == null) { DkmModuleId moduleId = new DkmModuleId(Guid.NewGuid(), DebugHelpers.NullcSymbolProviderGuid); processData.module = DkmModule.Create(moduleId, "nullc.embedded.code", processData.compilerId, process.Connection, null); } if (processData.moduleInstance == null && processData.nativeModuleInstance == null) { DkmDynamicSymbolFileId symbolFileId = DkmDynamicSymbolFileId.Create(DebugHelpers.NullcSymbolProviderGuid); if (DebugHelpers.useNativeInterfaces) { processData.nativeModuleInstance = DkmNativeModuleInstance.Create("nullc", "nullc.embedded.code", 0, null, symbolFileId, DkmModuleFlags.None, DkmModuleMemoryLayout.Unknown, 1, "nullc embedded code", processData.nativeRuntimeInstance, moduleBase, moduleSize, Microsoft.VisualStudio.Debugger.Clr.DkmClrHeaderStatus.NativeBinary, false, null, null, null); processData.nativeModuleInstance.SetModule(processData.module, true); // Can use reload? } else { processData.moduleInstance = DkmCustomModuleInstance.Create("nullc", "nullc.embedded.code", 0, processData.runtimeInstance, null, symbolFileId, DkmModuleFlags.None, DkmModuleMemoryLayout.Unknown, moduleBase, 1, moduleSize, "nullc embedded code", false, null, null, null); processData.moduleInstance.SetModule(processData.module, true); // Can use reload? } } } // Update bytecode var moduleBytecodeVersion = DebugHelpers.ReadPointerVariable(process, "nullcModuleBytecodeVersion").GetValueOrDefault(0); if (processData.moduleBytecodeLocation != 0 && moduleBytecodeVersion != processData.moduleBytecodeVersion) { processData.moduleBytecodeLocation = 0; processData.moduleBytecodeSize = 0; processData.moduleBytecodeRaw = null; processData.bytecode = null; } if (processData.moduleBytecodeLocation == 0) { processData.moduleBytecodeLocation = DebugHelpers.ReadPointerVariable(process, "nullcModuleBytecodeLocation").GetValueOrDefault(0); processData.moduleBytecodeSize = DebugHelpers.ReadPointerVariable(process, "nullcModuleBytecodeSize").GetValueOrDefault(0); processData.moduleBytecodeVersion = moduleBytecodeVersion; if (processData.moduleBytecodeLocation != 0) { processData.moduleBytecodeRaw = new byte[processData.moduleBytecodeSize]; process.ReadMemory(processData.moduleBytecodeLocation, DkmReadMemoryFlags.None, processData.moduleBytecodeRaw); processData.bytecode = new NullcBytecode(); processData.bytecode.ReadFrom(processData.moduleBytecodeRaw, DebugHelpers.Is64Bit(process)); // Notify local component about bytecode update var message = DkmCustomMessage.Create(process.Connection, process, DebugHelpers.NullcReloadSymbolsMessageGuid, 1, null, null); message.SendHigher(); } } } catch (Exception ex) { Console.WriteLine("OnProcessPause failed with: " + ex.ToString()); } }