Exemple #1
0
            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);
            }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        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."
                                )
                            );
                    }
                }
            }
        }
Exemple #4
0
        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);
            }
        }
Exemple #5
0
 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));
 }
Exemple #6
0
        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);
            }
        }
Exemple #10
0
            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());
                }
            }