/// <summary>
        /// Finds a module of given MVID in one of the processes being debugged and returns its baseline metadata.
        /// Shall only be called while in debug mode.
        /// Shall only be called on MTA thread.
        /// </summary>
        public DebuggeeModuleInfo TryGetBaselineModuleInfo(Guid mvid)
        {
            Contract.ThrowIfFalse(Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA);

            return(_baselineMetadata.GetOrAdd(mvid, m =>
            {
                using (DebuggerComponent.ManagedEditAndContinueService())
                {
                    var clrModuleInstance = FindClrModuleInstance(m);
                    if (clrModuleInstance == null)
                    {
                        return default;
                    }

                    if (!TryGetBaselineModuleInfo(clrModuleInstance, out var metadata, out var symReader))
                    {
                        return default;
                    }

                    // hook up a callback on module unload (the call blocks until the message is processed):
                    DkmCustomMessage.Create(
                        Connection: clrModuleInstance.Process.Connection,
                        Process: clrModuleInstance.Process,
                        SourceId: DebuggerService.MessageSourceId,
                        MessageCode: 0,
                        Parameter1: this,
                        Parameter2: clrModuleInstance).SendLower();

                    return new DebuggeeModuleInfo(metadata, symReader);
                }
        private static bool ShouldEnableChildDebugging(DkmProcess process, DebugProcessOptions options)
        {
            if (options.ChildDebuggingMode == ChildDebuggingMode.AlwaysAttach)
            {
                return(true);
            }

            if (options.ChildDebuggingMode == ChildDebuggingMode.UseDefault)
            {
                Logger.LogInfo(
                    "Requesting default child process debugging mode for process {0}.",
                    process.UniqueId);
                DkmCustomMessage attachRequest = DkmCustomMessage.Create(
                    process.Connection,
                    process,
                    PackageServices.VsPackageMessageGuid,
                    (int)VsPackageMessage.IsChildDebuggingEnabled,
                    process.UniqueId,
                    process.Connection.UniqueId);
                // This needs to happen synchronously in order to guarantee that child debugging is enabled
                // before the process finishes initializing.
                attachRequest.SendToVsService(PackageServices.DkmComponentEventHandler, true);
            }
            return(false);
        }
Esempio n. 3
0
        private static bool ShouldEnable(DkmProcess process)
        {
            var message = DkmCustomMessage.Create(
                process.Connection,
                process,
                s_messageSourceId,
                MessageCode: 1, // Is legacy EE enabled?
                Parameter1: null,
                Parameter2: null);

            try
            {
                var reply  = message.SendLower();
                var result = (int)reply.Parameter1;
                // Possible values are 0 = false, 1 = true, 2 = not ready.
                // At this point, we should only get 0 or 1, but to be
                // safe, treat values other than 0 or 1 as false.
                Debug.Assert(result == 0 || result == 1);
                return(result == 0);
            }
            catch (NotImplementedException)
            {
                return(false);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Finds a module of given MVID in one of the processes being debugged and returns its baseline metadata.
        /// Shall only be called while in debug mode.
        /// </summary>
        public ModuleMetadata TryGetBaselineMetadata(Guid mvid)
        {
            return(_baselineMetadata.GetOrAdd(mvid, m =>
            {
                using (DebuggerComponent.ManagedEditAndContinueService())
                {
                    var clrModuleInstance = FindClrModuleInstance(m);
                    if (clrModuleInstance == null)
                    {
                        return default;
                    }

                    var metadata = GetBaselineModuleMetadata(clrModuleInstance);
                    if (metadata == null)
                    {
                        return default;
                    }

                    // hook up a callback on module unload (the call blocks until the message is processed):
                    DkmCustomMessage.Create(
                        Connection: clrModuleInstance.Process.Connection,
                        Process: clrModuleInstance.Process,
                        SourceId: DebuggerService.MessageSourceId,
                        MessageCode: 0,
                        Parameter1: this,
                        Parameter2: clrModuleInstance).SendLower();

                    return metadata;
                }
            }));
        }
        public void StartDebugging(DebugSessionOptions options)
        {
            _debuggingService.OnBeforeDebuggingStateChanged(DebuggingState.Design, DebuggingState.Run);

            if ((options & DebugSessionOptions.EditAndContinueDisabled) == 0)
            {
                _encService = _workspace.Services.GetRequiredService <IEditAndContinueWorkspaceService>();

                // hook up a callbacks (the call blocks until the message is processed):
                using (DebuggerComponent.ManagedEditAndContinueService())
                {
                    DkmCustomMessage.Create(
                        Connection: null,
                        Process: null,
                        SourceId: DebuggerService.MessageSourceId,
                        MessageCode: 0,
                        Parameter1: _encService,
                        Parameter2: null).SendLower();
                }

                _encService.StartDebuggingSession();
            }
            else
            {
                _encService = null;
            }
        }
        DkmCustomMessage IDkmCustomMessageForwardReceiver.SendLower(DkmCustomMessage customMessage)
        {
            var process = customMessage.Process;

            if (customMessage.MessageCode == MessageToLocalWorker.fetchLuaSymbols)
            {
                var moduleUniqueId = new Guid(customMessage.Parameter1 as byte[]);

                var nativeModuleInstance = process.GetNativeRuntimeInstance().GetNativeModuleInstances().FirstOrDefault(el => el.UniqueId == moduleUniqueId);

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

                // Check if Lua library is loaded
                ulong luaNewState    = AttachmentHelpers.TryGetFunctionAddress(nativeModuleInstance, "lua_newstate", out _).GetValueOrDefault(0);
                ulong luaLibNewState = AttachmentHelpers.TryGetFunctionAddress(nativeModuleInstance, "luaL_newstate", out _).GetValueOrDefault(0);

                if (luaNewState != 0 || luaLibNewState != 0)
                {
                    var locations = new LuaLocationsMessage();

                    locations.luaExecuteAtStart = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaV_execute", out _).GetValueOrDefault(0);
                    locations.luaExecuteAtEnd   = AttachmentHelpers.TryGetFunctionAddressAtDebugEnd(nativeModuleInstance, "luaV_execute", out _).GetValueOrDefault(0);

                    if (luaNewState != 0)
                    {
                        locations.luaNewStateAtStart = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "lua_newstate", out _).GetValueOrDefault(0);
                        locations.luaNewStateAtEnd   = AttachmentHelpers.TryGetFunctionAddressAtDebugEnd(nativeModuleInstance, "lua_newstate", out _).GetValueOrDefault(0);
                    }
                    else
                    {
                        locations.luaNewStateAtStart = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_newstate", out _).GetValueOrDefault(0);
                        locations.luaNewStateAtEnd   = AttachmentHelpers.TryGetFunctionAddressAtDebugEnd(nativeModuleInstance, "luaL_newstate", out _).GetValueOrDefault(0);
                    }

                    locations.luaClose   = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "lua_close", out _).GetValueOrDefault(0);
                    locations.closeState = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "close_state", out _).GetValueOrDefault(0);

                    locations.luaLoadFileEx       = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_loadfilex", out _).GetValueOrDefault(0);
                    locations.luaLoadFile         = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_loadfile", out _).GetValueOrDefault(0);
                    locations.solCompatLoadFileEx = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "kp_compat53L_loadfilex", out _).GetValueOrDefault(0);

                    locations.luaLoadBufferEx = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_loadbufferx", out _).GetValueOrDefault(0);
                    locations.luaLoadBuffer   = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_loadbuffer", out _).GetValueOrDefault(0);

                    locations.luaLoad = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "lua_load", out _).GetValueOrDefault(0);

                    locations.luaError    = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaB_error", out _).GetValueOrDefault(0);
                    locations.luaRunError = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaG_runerror", out _).GetValueOrDefault(0);
                    locations.luaThrow    = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaD_throw", out _).GetValueOrDefault(0);

                    return(DkmCustomMessage.Create(process.Connection, process, MessageToLocal.guid, MessageToLocal.luaSymbols, locations.Encode(), null));
                }
            }

            return(null);
        }
Esempio n. 7
0
            public void SendHigher(DkmProcess process)
            {
                var stream = new MemoryStream();

                _serializer.WriteObject(stream, this);
                var message = DkmCustomMessage.Create(process.Connection, process, _sourceId, MessageCode, stream.ToArray(), null);

                message.SendHigher();
            }
Esempio n. 8
0
        void IDkmModuleSymbolsLoadedNotification.OnModuleSymbolsLoaded(DkmModuleInstance moduleInstance, DkmModule module, bool isReload, DkmWorkList workList, DkmEventDescriptor eventDescriptor)
        {
            var process = moduleInstance.Process;

            var engines = process.DebugLaunchSettings.EngineFilter;

            if (engines == null || !engines.Contains(AD7Engine.DebugEngineGuid))
            {
                return;
            }

            var pyrtInfo = process.GetPythonRuntimeInfo();

            var nativeModuleInstance = moduleInstance as DkmNativeModuleInstance;

            if (nativeModuleInstance != null)
            {
                if (PythonDLLs.CTypesNames.Contains(moduleInstance.Name))
                {
                    pyrtInfo.DLLs.CTypes = nativeModuleInstance;

                    var traceHelper = process.GetDataItem <TraceManagerLocalHelper>();
                    if (traceHelper != null)
                    {
                        traceHelper.OnCTypesLoaded(nativeModuleInstance);
                    }
                }
                else if (PythonDLLs.GetPythonLanguageVersion(nativeModuleInstance) != PythonLanguageVersion.None)
                {
                    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.GetPythonRuntimeInstance() != null)
            {
                return;
            }

            if (pyrtInfo.DLLs.Python != null && pyrtInfo.DLLs.Python.HasSymbols())
            {
                if (process.LivePart == null || pyrtInfo.DLLs.DebuggerHelper != null)
                {
                    CreatePythonRuntimeInstance(process);
                }
                else
                {
                    InjectHelperDll(process);
                }
            }
        }
Esempio n. 9
0
        public int OnCustomDebugEvent(ref Guid ProcessId, VsComponentMessage message)
        {
            try {
                VsPackageMessage code = (VsPackageMessage)message.MessageCode;
                switch (code)
                {
                case VsPackageMessage.AttachToChild:
                    int     parentId = (int)message.Parameter1;
                    int     childId  = (int)message.Parameter2;
                    Process proc     = Process.GetProcessById(childId);
                    if (proc != null)
                    {
                        DebugAttach.AttachToProcess(new Process[] { proc }, ChildDebuggingMode.AlwaysAttach);
                    }
                    break;

                case VsPackageMessage.IsChildDebuggingEnabled:
                    Guid processGuid    = (Guid)message.Parameter1;
                    Guid connectionGuid = (Guid)message.Parameter2;
                    DkmTransportConnection connection = DkmTransportConnection.FindConnection(connectionGuid);
                    if (connection != null)
                    {
                        if (IsChildDebuggingEnabledByDefault)
                        {
                            DkmCustomMessage response = DkmCustomMessage.Create(
                                connection,
                                null,
                                PackageServices.VsDebuggerMessageGuid,
                                (int)VsDebuggerMessage.EnableChildProcessDebugging,
                                processGuid,
                                null
                                );
                            response.SendLower();
                        }
                        else
                        {
                            Logger.Log(
                                "Not enabling child process debugging for process {0}.  " +
                                "Child debugging is disabled by default.",
                                processGuid);
                        }
                    }
                    break;
                }
            } catch (Exception exception) {
                Logger.LogException(
                    exception,
                    "An error occured while handling a VsPackage message.  HR=0x{0:X}",
                    exception.HResult);
            }
            return(0);
        }
        /// <summary>
        /// Called by the debugger when a debugging session starts and managed debugging is being used.
        /// </summary>
        public void StartDebugging()
        {
            // Hook up a callbacks (the call blocks until the message is processed).
            using (DebuggerComponent.ManagedEditAndContinueService())
            {
                DkmCustomMessage.Create(
                    Connection: null,
                    Process: null,
                    SourceId: DebuggerService.MessageSourceId,
                    MessageCode: 0,
                    Parameter1: this,
                    Parameter2: null).SendLower();
            }

            _debuggingService.OnBeforeDebuggingStateChanged(DebuggingState.Design, DebuggingState.Run);

            _encService.StartDebuggingSession();
        }
Esempio n. 11
0
        public DkmCustomMessage SendLower(DkmCustomMessage message)
        {
            object result;

            byte[]       bytes;
            MessageCodes messageCode = (MessageCodes)message.MessageCode;

            try
            {
                bytes  = (byte[])message.Parameter1;
                result = ProcessMessage(messageCode, bytes);
            }
            catch (Exception e)
            {
                result      = e.ToString();
                messageCode = MessageCodes.Exception;
            }

            bytes = MessageSerializer.Serialize(result);
            return(DkmCustomMessage.Create(message.Connection, message.Process, Guid.Empty, (int)messageCode, bytes, null));
        }
Esempio n. 12
0
        void createProcessTracer_OnFunctionExited(
            DkmStackWalkFrame frame,
            StackFrameAnalyzer frameAnalyzer)
        {
            try {
                ulong processInfoAddr = Convert.ToUInt64(
                    frameAnalyzer.GetArgumentValue(frame, "lpProcessInformation"));

                // Check the return address first, it should be in EAX.  CreateProcessAsUser and
                // CreateProcess both return 0 on failure.  If the function failed, there is no child to
                // attach to.
                if (0 == frame.VscxGetRegisterValue32(CpuRegister.Eax))
                {
                    return;
                }

                // The process was successfully created.  Extract the PID from the PROCESS_INFORMATION
                // output param.  An attachment request must happend through the EnvDTE, which can only
                // be accessed from the VsPackage, so a request must be sent via a component message.
                DkmProcess process = frame.Process;
                int        size    = Marshal.SizeOf(typeof(PROCESS_INFORMATION));
                byte[]     buffer  = new byte[size];
                process.ReadMemory(processInfoAddr, DkmReadMemoryFlags.None, buffer);
                PROCESS_INFORMATION info          = MarshalUtility.ByteArrayToStructure <PROCESS_INFORMATION>(buffer);
                DkmCustomMessage    attachRequest = DkmCustomMessage.Create(
                    process.Connection,
                    process,
                    PackageServices.VsPackageMessageGuid,
                    (int)VsPackageMessage.AttachToChild,
                    process.LivePart.Id,
                    info.dwProcessId);
                attachRequest.SendToVsService(PackageServices.DkmComponentEventHandler, false);
            } catch (Exception exception) {
                Logger.LogError(
                    exception,
                    "An error occured handling the exit breakpoint.  HR = 0x{0:X}",
                    exception.HResult);
            }
        }
        /// <summary>
        /// Finds a module of given MVID in one of the processes being debugged and returns its baseline metadata.
        /// Shall only be called while in debug mode.
        /// Shall only be called on MTA thread.
        /// </summary>
        /// <returns>Null, if the module with the specified MVID is not found.</returns>
        public DebuggeeModuleInfo TryGetBaselineModuleInfo(Guid mvid)
        {
            Contract.ThrowIfFalse(Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA);

            return(_baselineMetadata.GetOrAdd(mvid, m =>
            {
                using (DebuggerComponent.ManagedEditAndContinueService())
                {
                    var clrModuleInstance = EnumerateClrModuleInstances(m).FirstOrDefault();
                    if (clrModuleInstance == null)
                    {
                        return null;
                    }

                    // The DebuggeeModuleInfo holds on a pointer to module metadata and on a SymReader instance.
                    //
                    // The module metadata lifetime is that of the module instance, so we need to stop using the module
                    // as soon as the module instance is unloaded. We do so by associating a DataItem with the module
                    // instance and removing the metadata from our cache when the DataItem is disposed.
                    //
                    // The SymReader instance is shared across all instancese of the module.
                    if (!clrModuleInstance.TryGetModuleInfo(out var info))
                    {
                        return null;
                    }

                    // hook up a callback on module unload (the call blocks until the message is processed):
                    DkmCustomMessage.Create(
                        Connection: clrModuleInstance.Process.Connection,
                        Process: clrModuleInstance.Process,
                        SourceId: DebuggerService.MessageSourceId,
                        MessageCode: 0,
                        Parameter1: this,
                        Parameter2: clrModuleInstance).SendLower();

                    return info;
                }
Esempio n. 14
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();
                    }
                }
            }
        void IDkmRuntimeBreakpointReceived.OnRuntimeBreakpointReceived(DkmRuntimeBreakpoint runtimeBreakpoint, DkmThread thread, bool hasException, DkmEventDescriptorS eventDescriptor)
        {
            var process = thread.Process;

            var processData = DebugHelpers.GetOrCreateDataItem <LuaRemoteProcessData>(process);

            if (runtimeBreakpoint.SourceId == Guids.luaSupportBreakpointGuid)
            {
                if (processData.locations != null)
                {
                    if (runtimeBreakpoint.UniqueId == processData.locations.breakpointLuaHelperBreakpointHit)
                    {
                        // Breakpoint can get hit again after expression evaluation 'slips' the thread
                        if (processData.pauseBreakpoints)
                        {
                            return;
                        }

                        eventDescriptor.Suppress();

                        var breakpointPos = DebugHelpers.ReadUintVariable(process, processData.locations.helperBreakHitIdAddress);

                        if (!breakpointPos.HasValue)
                        {
                            return;
                        }

                        if (breakpointPos.Value < processData.activeBreakpoints.Count)
                        {
                            try
                            {
                                var breakpoint = processData.activeBreakpoints[(int)breakpointPos.Value];

                                if (breakpoint.runtimeBreakpoint != null)
                                {
                                    breakpoint.runtimeBreakpoint.OnHit(thread, false);
                                }
                            }
                            catch (System.ObjectDisposedException)
                            {
                                // Breakpoint was implicitly closed
                                processData.activeBreakpoints.RemoveAt((int)breakpointPos.Value);
                            }
                            catch (DkmException)
                            {
                                // In case another component evaluates a function
                            }
                        }

                        return;
                    }
                    else if (runtimeBreakpoint.UniqueId == processData.locations.breakpointLuaHelperStepComplete)
                    {
                        if (processData.activeStepper != null)
                        {
                            var activeStepper = processData.activeStepper;

                            ClearStepperData(process, processData);

                            activeStepper.OnStepComplete(thread, false);
                        }

                        return;
                    }
                    else if (runtimeBreakpoint.UniqueId == processData.locations.breakpointLuaHelperStepInto)
                    {
                        if (processData.activeStepper != null)
                        {
                            var activeStepper = processData.activeStepper;

                            ClearStepperData(process, processData);

                            activeStepper.OnStepComplete(thread, false);
                        }

                        return;
                    }
                    else if (runtimeBreakpoint.UniqueId == processData.locations.breakpointLuaHelperStepOut)
                    {
                        if (processData.activeStepper != null)
                        {
                            var activeStepper = processData.activeStepper;

                            ClearStepperData(process, processData);

                            activeStepper.OnStepComplete(thread, false);
                        }

                        return;
                    }
                }

                thread.GetCurrentFrameInfo(out ulong retAddr, out ulong frameBase, out ulong vframe);

                var data = new SupportBreakpointHitMessage
                {
                    breakpointId = runtimeBreakpoint.UniqueId,
                    threadId     = thread.UniqueId,
                    retAddr      = retAddr,
                    frameBase    = frameBase,
                    vframe       = vframe
                };

                var message = DkmCustomMessage.Create(process.Connection, process, MessageToLocal.guid, MessageToLocal.luaSupportBreakpointHit, data.Encode(), null);

                var response = message.SendHigher();

                if (response?.MessageCode == MessageToRemote.throwException)
                {
                    if (runtimeBreakpoint is DkmRuntimeInstructionBreakpoint runtimeInstructionBreakpoint)
                    {
                        var exceptionInformation = DkmCustomExceptionInformation.Create(processData.runtimeInstance, Guids.luaExceptionGuid, thread, runtimeInstructionBreakpoint.InstructionAddress, "LuaError", 0, DkmExceptionProcessingStage.Thrown | DkmExceptionProcessingStage.UserVisible | DkmExceptionProcessingStage.Unhandled, null, new ReadOnlyCollection <byte>(response.Parameter1 as byte[]));

                        exceptionInformation.OnDebugMonitorException();
                    }
                }
            }
        }
Esempio n. 16
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());
                }
            }