示例#1
0
        public SourceLocation(ReadOnlyCollection <byte> encodedLocation, DkmProcess process = null)
        {
            var buffer = encodedLocation.ToArray();

            using (var stream = new MemoryStream(buffer))
                using (var reader = new BinaryReader(stream)) {
                    FileName = reader.ReadString();
                    bool hasFunctionName = reader.ReadBoolean();
                    if (hasFunctionName)
                    {
                        FunctionName = reader.ReadString();
                    }
                    LineNumber = reader.ReadInt32();
                    bool hasNativeAddress = reader.ReadBoolean();
                    if (hasNativeAddress && process != null)
                    {
                        var ip  = reader.ReadUInt64();
                        var rva = reader.ReadUInt32();

                        NativeAddress = DkmNativeInstructionAddress.Create(
                            process.GetNativeRuntimeInstance(),
                            process.GetPythonRuntimeInfo().DLLs.Python,
                            rva,
                            new DkmNativeInstructionAddress.CPUInstruction(ip));
                    }
                    else
                    {
                        NativeAddress = null;
                    }
                }
        }
            public override void Handle(DkmProcess process)
            {
                var pyrtInfo      = process.GetPythonRuntimeInfo();
                var nativeModules = process.GetNativeRuntimeInstance().GetNativeModuleInstances();

                pyrtInfo.DLLs.Python = nativeModules.Single(mi => mi.UniqueId == PythonDllModuleInstanceId);

                if (DebuggerHelperDllModuleInstanceId != Guid.Empty)
                {
                    pyrtInfo.DLLs.DebuggerHelper = nativeModules.Single(mi => mi.UniqueId == DebuggerHelperDllModuleInstanceId);
                }
            }
示例#3
0
        public SourceLocation(ReadOnlyCollection <byte> encodedLocation, DkmProcess process = null)
        {
            var buffer = encodedLocation.ToArray();

            using (var stream = new MemoryStream(buffer))
                using (var reader = new BinaryReader(stream))
                {
                    FileName = reader.ReadString();
                    bool hasFunctionName = reader.ReadBoolean();
                    if (hasFunctionName)
                    {
                        FunctionName = reader.ReadString();
                    }
                    LineNumber = reader.ReadInt32();
                    bool hasNativeAddress = reader.ReadBoolean();
                    if (hasNativeAddress && process != null)
                    {
                        var ip  = reader.ReadUInt64();
                        var rva = reader.ReadUInt32();

                        PythonDLLs dlls             = process.GetPythonRuntimeInfo().DLLs;
                        DkmNativeModuleInstance dll = null;
                        switch (reader.ReadInt32())
                        {
                        case 0:
                            dll = dlls.Python;
                            break;

                        case 1:
                            dll = dlls.DebuggerHelper;
                            break;
                        }

                        if (dll != null)
                        {
                            NativeAddress = DkmNativeInstructionAddress.Create(
                                process.GetNativeRuntimeInstance(),
                                dll,
                                rva,
                                new DkmNativeInstructionAddress.CPUInstruction(ip));
                        }
                    }
                    else
                    {
                        NativeAddress = null;
                    }
                }
        }
示例#4
0
        public CppExpressionEvaluator(DkmThread thread, ulong frameBase, ulong vframe)
        {
            _process = thread.Process;

            var inspectionSession = DkmInspectionSession.Create(_process, null);

            _cppInspectionContext = DkmInspectionContext.Create(inspectionSession, _process.GetNativeRuntimeInstance(), thread, Timeout,
                                                                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, 10, CppLanguage, null);

            const int CV_ALLREG_VFRAME = 0x00007536;
            var       vframeReg        = DkmUnwoundRegister.Create(CV_ALLREG_VFRAME, new ReadOnlyCollection <byte>(BitConverter.GetBytes(vframe)));
            var       regs             = thread.GetCurrentRegisters(new[] { vframeReg });
            var       iaddr            = _process.CreateNativeInstructionAddress(regs.GetInstructionPointer());

            _nativeFrame = DkmStackWalkFrame.Create(thread, iaddr, frameBase, 0, DkmStackWalkFrameFlags.None, null, regs, null);
        }
示例#5
0
        internal static ulong?ReadPointerVariable(DkmProcess process, string name)
        {
            var runtimeInstance = process.GetNativeRuntimeInstance();

            if (runtimeInstance != null)
            {
                foreach (var module in runtimeInstance.GetModuleInstances())
                {
                    var nativeModule = module as DkmNativeModuleInstance;

                    var variableAddress = nativeModule?.FindExportName(name, IgnoreDataExports: false);

                    if (variableAddress != null)
                    {
                        return(ReadPointerVariable(process, variableAddress.CPUInstructionPart.InstructionPointer));
                    }
                }
            }

            return(null);
        }
示例#6
0
            public override void Handle(DkmProcess process)
            {
                var pyrtInfo      = process.GetPythonRuntimeInfo();
                var nativeModules = process.GetNativeRuntimeInstance().GetNativeModuleInstances();

                pyrtInfo.DLLs.Python = nativeModules.Single(mi => mi.UniqueId == PythonDllModuleInstanceId);
                pyrtInfo.DLLs.Python.FlagAsTransitionModule();

                if (DebuggerHelperDllModuleInstanceId != Guid.Empty)
                {
                    pyrtInfo.DLLs.DebuggerHelper = nativeModules.Single(mi => mi.UniqueId == DebuggerHelperDllModuleInstanceId);
                    pyrtInfo.DLLs.DebuggerHelper.FlagAsTransitionModule();

                    process.SetDataItem(DkmDataCreationDisposition.CreateNew, new TraceManager(process));
                }

                var runtimeId       = new DkmRuntimeInstanceId(Guids.PythonRuntimeTypeGuid, 0);
                var runtimeInstance = DkmCustomRuntimeInstance.Create(process, runtimeId, null);

                new CreateModuleRequest {
                    ModuleId = Guids.UnknownPythonModuleGuid
                }.Handle(process);
            }
示例#7
0
            public override void Handle(DkmProcess process)
            {
                if (process.LivePart == null)
                {
                    // When debugging dumps, there's no stepping or live expression evaluation. Hence, we don't
                    // need the helper DLL nor _ctypes.pyd for anything, and even if they are loaded in the dump,
                    // we don't care about them at all.
                    return;
                }

                var pyrtInfo       = process.GetPythonRuntimeInfo();
                var moduleInstance = process.GetNativeRuntimeInstance().GetNativeModuleInstances().Single(mi => mi.UniqueId == ModuleInstanceId);

                if (pyrtInfo.DLLs.CTypes == null && PythonDLLs.CTypesNames.Contains(moduleInstance.Name))
                {
                    moduleInstance.TryLoadSymbols();
                    if (moduleInstance.HasSymbols())
                    {
                        pyrtInfo.DLLs.CTypes = moduleInstance;

                        var traceHelper = process.GetDataItem <TraceManagerLocalHelper>();
                        if (traceHelper != null)
                        {
                            traceHelper.OnCTypesLoaded(moduleInstance);
                        }
                    }
                }

                if (process.GetPythonRuntimeInstance() != null)
                {
                    return;
                }

                if (PythonDLLs.GetPythonLanguageVersion(moduleInstance) != PythonLanguageVersion.None)
                {
                    pyrtInfo.DLLs.Python = moduleInstance;
                    for (int i = 0; i < 2; ++i)
                    {
                        if (moduleInstance.HasSymbols())
                        {
                            if (IsModuleCompiledWithPGO(moduleInstance))
                            {
                                pyrtInfo.DLLs.Python = null;
                                var pgoWarnMsg = DkmCustomMessage.Create(process.Connection, process, Guid.Empty, (int)VsPackageMessage.WarnAboutPGO, moduleInstance.Name, null);
                                pgoWarnMsg.SendToVsService(Guids.CustomDebuggerEventHandlerGuid, IsBlocking: true);
                                return;
                            }

                            if (process.LivePart == null)
                            {
                                // If debugging crash dumps, runtime can be created as soon as Python symbols are resolved.
                                CreatePythonRuntimeInstance(process);
                            }
                            else
                            {
                                // If not, we need to check for debugger helper DLL as well, and inject it if it isn't there yet.
                                if (pyrtInfo.DLLs.DebuggerHelper != null)
                                {
                                    CreatePythonRuntimeInstance(process);
                                }
                                else
                                {
                                    InjectHelperDll(process);
                                }
                            }
                            return;
                        }

                        moduleInstance.TryLoadSymbols();
                    }

                    var symWarnMsg = DkmCustomMessage.Create(process.Connection, process, Guid.Empty, (int)VsPackageMessage.WarnAboutPythonSymbols, moduleInstance.Name, null);
                    symWarnMsg.SendToVsService(Guids.CustomDebuggerEventHandlerGuid, IsBlocking: true);
                }
                else if (PythonDLLs.DebuggerHelperNames.Contains(moduleInstance.Name))
                {
                    moduleInstance.TryLoadSymbols();

                    // When the module is reported is loaded, it is not necessarily fully initialized yet - it is possible to get into a state
                    // where its import table is not processed yet. If we register TraceFunc and it gets called by Python when in that state,
                    // we'll get a crash as soon as any imported WinAPI function is called. So check whether DllMain has already run - if it
                    // is, we're good to go, and if not, set a breakpoint on a hook that will be called once it is run, and defer runtime
                    // creation until that breakpoint is hit.

                    bool isInitialized = moduleInstance.GetExportedStaticVariable <ByteProxy>("isInitialized").Read() != 0;
                    if (isInitialized)
                    {
                        OnHelperDllInitialized(moduleInstance);
                    }
                    else
                    {
                        DkmRuntimeBreakpoint initBP = null;
                        initBP = CreateRuntimeDllExportedFunctionBreakpoint(moduleInstance, "OnInitialized", (thread, frameBase, vFrame) => {
                            initBP.Close();
                            OnHelperDllInitialized(moduleInstance);
                        });
                        initBP.Enable();
                    }
                }
            }
示例#8
0
        public CppExpressionEvaluator(DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame)
        {
            _process = stackFrame.Process;
            var thread = stackFrame.Thread;

            if (stackFrame.InstructionAddress is DkmNativeInstructionAddress)
            {
                _nativeFrame = stackFrame;
            }
            else
            {
                var customAddr = stackFrame.InstructionAddress as DkmCustomInstructionAddress;
                if (customAddr == null)
                {
                    throw new ArgumentException();
                }

                var loc = new SourceLocation(customAddr.AdditionalData, _process);
                if (loc.NativeAddress == null)
                {
                    throw new ArgumentException();
                }

                _nativeFrame = DkmStackWalkFrame.Create(thread, loc.NativeAddress, stackFrame.FrameBase, stackFrame.FrameSize,
                                                        DkmStackWalkFrameFlags.None, null, stackFrame.Registers, null);
            }

            _cppInspectionContext = DkmInspectionContext.Create(inspectionContext.InspectionSession, _process.GetNativeRuntimeInstance(), thread, Timeout,
                                                                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, inspectionContext.Radix, CppLanguage, null);
        }
示例#9
0
        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));
            }
        }
示例#10
0
        internal static string EvaluateValueAtLuaValue(DkmProcess process, LuaValueDataBase valueBase, uint radix, out string editableValue, ref DkmEvaluationResultFlags flags, out DkmDataAddress dataAddress, out string type)
        {
            editableValue = null;
            dataAddress   = null;
            type          = "unknown";

            if (valueBase == null)
            {
                return(null);
            }

            if (valueBase as LuaValueDataNil != null)
            {
                type = "nil";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly;
                return("nil");
            }

            if (valueBase as LuaValueDataBool != null)
            {
                var value = valueBase as LuaValueDataBool;

                type = "bool";

                if (value.value)
                {
                    flags        |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.Boolean | DkmEvaluationResultFlags.BooleanTrue;
                    editableValue = $"{value.value}";
                    return("true");
                }
                else
                {
                    flags        |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.Boolean;
                    editableValue = $"{value.value}";
                    return("false");
                }
            }

            if (valueBase as LuaValueDataLightUserData != null)
            {
                var value = valueBase as LuaValueDataLightUserData;

                type = "user_data";

                flags        |= DkmEvaluationResultFlags.IsBuiltInType;
                editableValue = $"{value.value}";
                return($"0x{value.value:x}");
            }

            if (valueBase as LuaValueDataNumber != null)
            {
                var value = valueBase as LuaValueDataNumber;

                if (value.extendedType == LuaHelpers.GetIntegerNumberExtendedType())
                {
                    type = "int";

                    flags        |= DkmEvaluationResultFlags.IsBuiltInType;
                    editableValue = $"{value.value}";

                    if (radix == 16)
                    {
                        return($"0x{(int)value.value:x8}");
                    }

                    return($"{value.value}");
                }
                else
                {
                    type = "double";

                    flags        |= DkmEvaluationResultFlags.IsBuiltInType;
                    editableValue = $"{value.value}";
                    return($"{value.value}");
                }
            }

            if (valueBase as LuaValueDataString != null)
            {
                var value = valueBase as LuaValueDataString;

                type = value.extendedType == LuaExtendedType.ShortString ? "short_string" : "long_string";

                flags        |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.RawString;
                editableValue = $"{value.value}";
                dataAddress   = DkmDataAddress.Create(process.GetNativeRuntimeInstance(), value.targetAddress, null);
                return($"0x{value.targetAddress:x} \"{value.value}\"");
            }

            if (valueBase as LuaValueDataTable != null)
            {
                var value = valueBase as LuaValueDataTable;

                type = "table";

                flags |= DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;

                var arrayElementCount = value.value.GetArrayElementCount(process);
                var nodeElementCount  = value.value.GetNodeElementCount(process);

                if (arrayElementCount != 0 && nodeElementCount != 0)
                {
                    return($"0x{value.targetAddress:x} table [{arrayElementCount} element(s) and {nodeElementCount} key(s)]");
                }

                if (arrayElementCount != 0)
                {
                    return($"0x{value.targetAddress:x} table [{arrayElementCount} element(s)]");
                }

                if (nodeElementCount != 0)
                {
                    return($"0x{value.targetAddress:x} table [{nodeElementCount} key(s)]");
                }

                if (!value.value.HasMetaTable())
                {
                    flags &= ~DkmEvaluationResultFlags.Expandable;

                    return($"0x{value.targetAddress:x} table [empty]");
                }

                return($"0x{value.targetAddress:x} table");
            }

            if (valueBase as LuaValueDataLuaFunction != null)
            {
                var value = valueBase as LuaValueDataLuaFunction;

                type = "lua_function";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;
                return($"0x{value.targetAddress:x}");
            }

            if (valueBase as LuaValueDataExternalFunction != null)
            {
                var value = valueBase as LuaValueDataExternalFunction;

                type = "c_function";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;
                return($"0x{value.targetAddress:x}");
            }

            if (valueBase as LuaValueDataExternalClosure != null)
            {
                var value = valueBase as LuaValueDataExternalClosure;

                type = "c_closure";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;
                return($"0x{value.targetAddress:x}");
            }

            if (valueBase as LuaValueDataUserData != null)
            {
                var value = valueBase as LuaValueDataUserData;

                type = "user_data";

                flags |= DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;
                return($"0x{value.targetAddress:x}");
            }

            if (valueBase as LuaValueDataThread != null)
            {
                var value = valueBase as LuaValueDataThread;

                type = "thread";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly;
                return($"0x{value.targetAddress:x}");
            }

            return(null);
        }
示例#11
0
            void IDkmInstructionAddressProvider.GetInstructionAddress(DkmProcess process, DkmWorkList workList, ulong instructionPointer, DkmCompletionRoutine <DkmGetInstructionAddressAsyncResult> completionRoutine)
            {
                var processData = DebugHelpers.GetOrCreateDataItem <NullcModuleDataItem>(process);

                if (!processData.nullcIsMissing && processData.moduleBase == 0)
                {
                    processData.moduleBase = DebugHelpers.ReadPointerVariable(process, "nullcModuleStartAddress").GetValueOrDefault(0);

                    processData.moduleSize = (uint)(DebugHelpers.ReadPointerVariable(process, "nullcModuleEndAddress").GetValueOrDefault(0) - processData.moduleBase);

                    processData.nullcIsMissing = processData.moduleBase == 0;
                }

                if (processData.moduleBase != 0)
                {
                    if (instructionPointer >= processData.moduleBase && instructionPointer < processData.moduleBase + processData.moduleSize)
                    {
                        DkmInstructionAddress address;

                        if (DebugHelpers.useNativeInterfaces)
                        {
                            var nullcNativeRuntime  = DebugHelpers.useDefaultRuntimeInstance ? process.GetNativeRuntimeInstance() : process.GetRuntimeInstances().OfType <DkmNativeRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcRuntimeGuid);
                            var nullcModuleInstance = nullcNativeRuntime.GetModuleInstances().OfType <DkmNativeModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid);

                            address = DkmNativeInstructionAddress.Create(nullcNativeRuntime, nullcModuleInstance, (uint)(instructionPointer - processData.moduleBase), new DkmInstructionAddress.CPUInstruction(instructionPointer));
                        }
                        else
                        {
                            var nullcNativeRuntime  = process.GetRuntimeInstances().OfType <DkmCustomRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcRuntimeGuid);
                            var nullcModuleInstance = nullcNativeRuntime.GetModuleInstances().OfType <DkmCustomModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid);

                            address = DkmCustomInstructionAddress.Create(nullcNativeRuntime, nullcModuleInstance, null, instructionPointer, null, new DkmInstructionAddress.CPUInstruction(instructionPointer));
                        }

                        completionRoutine(new DkmGetInstructionAddressAsyncResult(address, true));
                        return;
                    }
                }

                process.GetInstructionAddress(workList, instructionPointer, completionRoutine);
            }
示例#12
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());
                }
            }