예제 #1
0
            void IDkmDebugMonitorExceptionNotification.OnDebugMonitorException(DkmExceptionInformation exception, DkmWorkList workList, DkmEventDescriptorS eventDescriptor)
            {
                var processData = DebugHelpers.GetOrCreateDataItem <NullcRemoteProcessDataItem>(exception.Process);

                if (exception.InstructionAddress == null)
                {
                    return;
                }

                ulong address = exception.InstructionAddress.CPUInstructionPart.InstructionPointer;

                // Breakpoint
                if (exception.Code == 0x80000003)
                {
                    // Internal stepper breakpoints are silenced but te debugger is notified to break the process
                    if (processData.stepBreakpoint != null && processData.stepBreakpoint.InstructionAddress.CPUInstructionPart.InstructionPointer == address)
                    {
                        eventDescriptor.Suppress();

                        exception.Thread.OnEmbeddedBreakpointHit(exception.InstructionAddress, false);
                    }

                    if (processData.secondaryStepBreakpoint != null && processData.secondaryStepBreakpoint.InstructionAddress.CPUInstructionPart.InstructionPointer == address)
                    {
                        eventDescriptor.Suppress();

                        exception.Thread.OnEmbeddedBreakpointHit(exception.InstructionAddress, false);
                    }

                    // Second stage of breakpoint handling - supress exception, notify debugger to break the process and remember what breakpoint has to be resotred later
                    if (processData.activeBreakpointLocations.Contains(address))
                    {
                        eventDescriptor.Suppress();

                        exception.Thread.OnEmbeddedBreakpointHit(exception.InstructionAddress, false);

                        // Schedule restore of this breakpoint when process continues
                        processData.lastHitBreakpointLocation = address;

                        processData.singleStepThread = exception.Thread;
                    }
                }
            }
예제 #2
0
        void IDkmExceptionTriggerHitNotification.OnExceptionTriggerHit(DkmExceptionTriggerHit hit, DkmEventDescriptorS eventDescriptor)
        {
            ThreadHelper.JoinableTaskFactory.Run(async() => {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                var exceptionInfo = hit.Exception as VisualStudio.Debugger.Native.DkmWin32ExceptionInformation;

                if (exceptionInfo.Code == RemoteDebugStartExceptionCode)
                {
                    // Parameters expected are the flag to indicate the debugger is present and JSON to write to the target for configuration
                    // of the debugger
                    const int exceptionParameterCount = 3;

                    if (exceptionInfo.ExceptionParameters.Count == exceptionParameterCount)
                    {
                        // If we have a port and debug id, we'll go ahead and tell the client we are present
                        if (Instance.AttachRemoteProcessFunction != null && Instance.RemoteDebugCommandInfo != null)
                        {
                            if (Instance.RemoteDebugCommandInfo.Length <= (int)exceptionInfo.ExceptionParameters[2])
                            {
                                // Write back that debugger is present
                                hit.Process.WriteMemory(exceptionInfo.ExceptionParameters[0], BitConverter.GetBytes(true));

                                // Write back the details of the debugger arguments
                                hit.Process.WriteMemory(exceptionInfo.ExceptionParameters[1], Instance.RemoteDebugCommandInfo);
                            }
                        }
                    }
                }
                else if (exceptionInfo.Code == RemoteDebugAttachExceptionCode)
                {
                    // Parameters expected are the flag to indicate the debugger is present and XML to write to the target for configuration
                    // of the debugger
                    const int exceptionAttachParameterCount = 1;

                    if (exceptionInfo.ExceptionParameters.Count == exceptionAttachParameterCount)
                    {
                        // If we have a port and debug id, we'll go ahead and tell the client we are present
                        if (Instance.AttachRemoteProcessFunction != null)
                        {
                            // Write back that debugger is present
                            hit.Process.WriteMemory(exceptionInfo.ExceptionParameters[0], BitConverter.GetBytes(true));

                            // Start the task to attach to the remote Python debugger session
                            StartAttachRemoteProcess();
                        }
                    }
                }
            });

            eventDescriptor.Suppress();
        }
예제 #3
0
            void IDkmSingleStepCompleteReceived.OnSingleStepCompleteReceived(DkmSingleStepRequest singleStepRequest, DkmEventDescriptorS eventDescriptor)
            {
                var processData = DebugHelpers.GetOrCreateDataItem <NullcRemoteProcessDataItem>(singleStepRequest.Thread.Process);

                // Last stage of breakpoint handling - restore debug break instruction now that we have moved from the breakpoint location
                if (processData.lastHitBreakpointLocation != 0)
                {
                    // Restore breakpoint instruction
                    singleStepRequest.Thread.Process.InvisibleWriteMemory(processData.lastHitBreakpointLocation, new byte[1] {
                        0xcc
                    });

                    processData.lastHitBreakpointLocation = 0;

                    eventDescriptor.Suppress();
                }
            }
        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();
                    }
                }
            }
        }
예제 #5
0
        void IDkmExceptionTriggerHitNotification.OnExceptionTriggerHit(DkmExceptionTriggerHit hit, DkmEventDescriptorS eventDescriptor) {
            ThreadHelper.Generic.Invoke(() => {
                var exceptionInfo = hit.Exception as VisualStudio.Debugger.Native.DkmWin32ExceptionInformation;

                if (exceptionInfo.Code == RemoteDebugStartExceptionCode) {
                    // Parameters expected are the flag to indicate the debugger is present and JSON to write to the target for configuration
                    // of the debugger
                    const int exceptionParameterCount = 3;

                    if (exceptionInfo.ExceptionParameters.Count == exceptionParameterCount) {
                        // If we have a port and debug id, we'll go ahead and tell the client we are present
                        if (Instance.AttachRemoteProcessFunction != null && Instance.RemoteDebugCommandInfo != null) {
                            if (Instance.RemoteDebugCommandInfo.Length <= (int)exceptionInfo.ExceptionParameters[2]) {
                                // Write back that debugger is present
                                hit.Process.WriteMemory(exceptionInfo.ExceptionParameters[0], BitConverter.GetBytes(true));

                                // Write back the details of the debugger arguments
                                hit.Process.WriteMemory(exceptionInfo.ExceptionParameters[1], Instance.RemoteDebugCommandInfo);
                            }
                        }
                    }
                } else if (exceptionInfo.Code == RemoteDebugAttachExceptionCode) {
                    // Parameters expected are the flag to indicate the debugger is present and XML to write to the target for configuration
                    // of the debugger
                    const int exceptionAttachParameterCount = 1;

                    if (exceptionInfo.ExceptionParameters.Count == exceptionAttachParameterCount) {
                        // If we have a port and debug id, we'll go ahead and tell the client we are present
                        if (Instance.AttachRemoteProcessFunction != null) {
                            // Write back that debugger is present
                            hit.Process.WriteMemory(exceptionInfo.ExceptionParameters[0], BitConverter.GetBytes(true));

                            // Start the task to attach to the remote Python debugger session
                            System.Threading.Tasks.Task.Factory.StartNew(Instance.AttachRemoteProcessFunction);
                        }
                    }
                }
            });

            eventDescriptor.Suppress();
        }