Ejemplo n.º 1
0
        void IFunctionTracer.OnExitBreakpointHit(DkmRuntimeBreakpoint bp, DkmThread thread, bool hasException)
        {
            FunctionTraceEntryDataItem traceDataItem = bp.GetDataItem <FunctionTraceEntryDataItem>();

            if (OnFunctionExited != null)
            {
                DkmStackWalkFrame  frame        = thread.GetTopStackWalkFrame(bp.RuntimeInstance);
                StackFrameAnalyzer exitAnalyzer = null;
                if (traceDataItem != null)
                {
                    DkmSystemInformationFlags systemInformationFlags =
                        frame.ModuleInstance.Process.SystemInformation.Flags;
                    bool isTarget64Bit = systemInformationFlags.HasFlag(DkmSystemInformationFlags.Is64Bit);
                    int  pointerSize   = (isTarget64Bit) ? 8 : 4;
                    exitAnalyzer = new CachedFrameAnalyzer(
                        frameAnalyzer.Parameters,
                        traceDataItem.EntryArgumentValues,
                        pointerSize);
                }
                OnFunctionExited(frame, exitAnalyzer);
            }

            // Since this was a one-shot breakpoint, it is unconditionally closed.
            bp.Close();
        }
Ejemplo n.º 2
0
        void IDkmRuntimeMonitorBreakpointHandler.EnableRuntimeBreakpoint(DkmRuntimeBreakpoint runtimeBreakpoint)
        {
            var bp = runtimeBreakpoint as DkmRuntimeInstructionBreakpoint;

            if (bp == null)
            {
                Debug.Fail("Non-Python breakpoint passed to EnableRuntimeBreakpoint.");
                throw new NotImplementedException();
            }

            var instrAddr = bp.InstructionAddress as DkmCustomInstructionAddress;

            if (instrAddr == null || instrAddr.RuntimeInstance.Id.RuntimeType != Guids.PythonRuntimeTypeGuid)
            {
                Debug.Fail("Non-Python breakpoint passed to EnableRuntimeBreakpoint.");
                throw new NotImplementedException();
            }

            var traceManager = bp.Process.GetDataItem <TraceManager>();

            if (traceManager == null)
            {
                Debug.Fail("EnableRuntimeBreakpoint called before TraceMananger is initialized.");
                throw new InvalidOperationException();
            }

            var loc = new SourceLocation(instrAddr.AdditionalData);

            bp.SetDataItem(DkmDataCreationDisposition.CreateNew, loc);
            traceManager.AddBreakpoint(bp);
        }
Ejemplo n.º 3
0
 void IDkmRuntimeBreakpointReceived.OnRuntimeBreakpointReceived(DkmRuntimeBreakpoint runtimeBreakpoint, DkmThread thread, bool hasException, DkmEventDescriptorS eventDescriptor)
 {
     if (runtimeBreakpoint.SourceId == Guids.LocalComponentGuid)
     {
         ulong retAddr, frameBase, vframe;
         thread.GetCurrentFrameInfo(out retAddr, out frameBase, out vframe);
         new LocalComponent.HandleBreakpointRequest {
             BreakpointId  = runtimeBreakpoint.UniqueId,
             ThreadId      = thread.UniqueId,
             FrameBase     = frameBase,
             VFrame        = vframe,
             ReturnAddress = retAddr
         }.SendHigher(thread.Process);
     }
     else if (runtimeBreakpoint.SourceId == Guids.PythonTraceManagerSourceGuid || runtimeBreakpoint.SourceId == Guids.PythonStepTargetSourceGuid)
     {
         var traceManager = runtimeBreakpoint.Process.GetDataItem <TraceManager>();
         if (traceManager != null)
         {
             traceManager.OnNativeBreakpointHit(runtimeBreakpoint, thread);
         }
     }
     else
     {
         Debug.Fail("RemoteComponent received a notification for a breakpoint that it does not know how to handle.");
         throw new ArgumentException();
     }
 }
Ejemplo n.º 4
0
        void IFunctionTracer.OnEntryBreakpointHit(DkmRuntimeBreakpoint bp, DkmThread thread, bool hasException)
        {
            // The function was just entered.  Install the exit breakpoint on the calling thread at the
            // return address, and notify any listeners.
            DkmStackWalkFrame frame = thread.GetTopStackWalkFrame(bp.RuntimeInstance);

            bool suppressExitBreakpoint = false;

            if (OnFunctionEntered != null)
            {
                OnFunctionEntered(frame, frameAnalyzer, out suppressExitBreakpoint);
            }

            if (!suppressExitBreakpoint)
            {
                ulong ret = frame.VscxGetReturnAddress();

                DkmInstructionAddress           retAddr = thread.Process.CreateNativeInstructionAddress(ret);
                DkmRuntimeInstructionBreakpoint exitBp  = DkmRuntimeInstructionBreakpoint.Create(
                    Guids.Source.FunctionTraceExit, thread, retAddr, false, null);
                // Capture the value of every argument now, since when the exit breakpoint gets hit, the
                // target function will have already returned and its frame will be cleaned up.
                exitBp.SetDataItem(DkmDataCreationDisposition.CreateAlways,
                                   new FunctionTraceEntryDataItem {
                    EntryArgumentValues = frameAnalyzer.GetAllArgumentValues(frame)
                });
                exitBp.SetDataItem(DkmDataCreationDisposition.CreateAlways,
                                   new FunctionTraceDataItem {
                    Tracer = this
                });
                exitBp.Enable();
            }
        }
Ejemplo n.º 5
0
            void IDkmRuntimeMonitorBreakpointHandler.DisableRuntimeBreakpoint(DkmRuntimeBreakpoint runtimeBreakpoint)
            {
                var breakpointData = runtimeBreakpoint.GetDataItem <NullcBreakpointDataItem>();

                if (breakpointData != null)
                {
                    var processData = DebugHelpers.GetOrCreateDataItem <NullcRemoteProcessDataItem>(runtimeBreakpoint.Process);

                    var address = breakpointData.instructionAddress.CPUInstructionPart.InstructionPointer;

                    runtimeBreakpoint.Process.InvisibleWriteMemory(breakpointData.instructionAddress.CPUInstructionPart.InstructionPointer, breakpointData.prevValue);

                    // Skip internal breakpoints used in stepper
                    if (runtimeBreakpoint.SourceId != DebugHelpers.NullcStepperBreakpointSourceId)
                    {
                        if (processData.activeBreakpointLocations.Contains(address))
                        {
                            processData.activeBreakpointLocations.Remove(address);
                        }

                        // If we were planning to restore the breakpoint, forget about it
                        if (processData.lastHitBreakpointLocation == address)
                        {
                            processData.lastHitBreakpointLocation = 0;
                        }
                    }
                }
            }
        void IDkmRuntimeMonitorBreakpointHandler.EnableRuntimeBreakpoint(DkmRuntimeBreakpoint runtimeBreakpoint)
        {
            var process = runtimeBreakpoint.Process;

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

            var runtimeInstructionBreakpoint = runtimeBreakpoint as DkmRuntimeInstructionBreakpoint;

            if (runtimeInstructionBreakpoint != null)
            {
                var customInstructionAddress = runtimeInstructionBreakpoint.InstructionAddress as DkmCustomInstructionAddress;

                if (customInstructionAddress != null)
                {
                    LuaAddressEntityData entityData = new LuaAddressEntityData();

                    entityData.ReadFrom(customInstructionAddress.EntityId.ToArray());

                    var breakpoint = new LuaBreakpoint
                    {
                        source = entityData.source,
                        line   = entityData.line,

                        functionAddress = entityData.functionAddress,

                        runtimeBreakpoint = runtimeBreakpoint
                    };

                    processData.activeBreakpoints.Add(breakpoint);
                    UpdateBreakpoints(process, processData);
                }
            }
        }
Ejemplo n.º 7
0
        public TraceManager(DkmProcess process)
        {
            _process  = process;
            _pyrtInfo = process.GetPythonRuntimeInfo();

            _breakpointData                 = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <ArrayProxy <CliStructProxy <BreakpointData> > >("breakpointData");
            _currentBreakpointData          = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <ByteProxy>("currentBreakpointData");
            _breakpointDataInUseByTraceFunc = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <ByteProxy>("breakpointDataInUseByTraceFunc");
            _currentSourceLocation          = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <CliStructProxy <CurrentSourceLocation> >("currentSourceLocation");
            _stepKind           = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <Int32Proxy>("stepKind");
            _stepThreadId       = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <UInt64Proxy>("stepThreadId");
            _steppingStackDepth = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <Int32Proxy>("steppingStackDepth");

            var onBreakpointHit = _pyrtInfo.DLLs.DebuggerHelper.FindExportName("OnBreakpointHit", true);

            _onBreakpointHitBP = DkmRuntimeInstructionBreakpoint.Create(Guids.PythonTraceManagerSourceGuid, null, onBreakpointHit, false, null);
            _onBreakpointHitBP.Enable();

            var onStepComplete = _pyrtInfo.DLLs.DebuggerHelper.FindExportName("OnStepComplete", true);

            _onStepCompleteBP = DkmRuntimeInstructionBreakpoint.Create(Guids.PythonTraceManagerSourceGuid, null, onStepComplete, false, null);
            _onStepCompleteBP.Enable();

            var onStepFallThrough = _pyrtInfo.DLLs.DebuggerHelper.FindExportName("OnStepFallThrough", true);

            _onStepFallThroughBP = DkmRuntimeInstructionBreakpoint.Create(Guids.PythonTraceManagerSourceGuid, null, onStepFallThrough, false, null);
            _onStepFallThroughBP.Enable();

            WriteBreakpoints();
        }
Ejemplo n.º 8
0
    void IFunctionTracer.OnEntryBreakpointHit(DkmRuntimeBreakpoint bp, DkmThread thread, bool hasException) {
      // The function was just entered.  Install the exit breakpoint on the calling thread at the
      // return address, and notify any listeners.
      DkmStackWalkFrame frame = thread.GetTopStackWalkFrame(bp.RuntimeInstance);

      bool suppressExitBreakpoint = false;
      if (OnFunctionEntered != null)
        OnFunctionEntered(frame, frameAnalyzer, out suppressExitBreakpoint);

      if (!suppressExitBreakpoint) {
        ulong ret = frame.VscxGetReturnAddress();

        DkmInstructionAddress retAddr = thread.Process.CreateNativeInstructionAddress(ret);
        DkmRuntimeInstructionBreakpoint exitBp = DkmRuntimeInstructionBreakpoint.Create(
            Guids.Source.FunctionTraceExit, thread, retAddr, false, null);
        // Capture the value of every argument now, since when the exit breakpoint gets hit, the
        // target function will have already returned and its frame will be cleaned up.
        exitBp.SetDataItem(DkmDataCreationDisposition.CreateAlways,
            new FunctionTraceEntryDataItem { 
                EntryArgumentValues = frameAnalyzer.GetAllArgumentValues(frame) 
            });
        exitBp.SetDataItem(DkmDataCreationDisposition.CreateAlways,
            new FunctionTraceDataItem { Tracer = this });
        exitBp.Enable();
      }
    }
Ejemplo n.º 9
0
        void IDkmRuntimeMonitorBreakpointHandler.TestRuntimeBreakpoint(DkmRuntimeBreakpoint runtimeBreakpoint)
        {
            var traceManager = runtimeBreakpoint.Process.GetDataItem <TraceManager>();

            if (traceManager == null)
            {
                Debug.Fail("TestRuntimeBreakpoint called before TraceMananger is initialized.");
                throw new InvalidOperationException();
            }
        }
Ejemplo n.º 10
0
        public void AddBreakpoint(DkmRuntimeBreakpoint bp)
        {
            var loc = bp.GetDataItem <SourceLocation>();

            if (!_breakpoints.TryGetValue(loc, out List <DkmRuntimeBreakpoint> bpsAtLoc))
            {
                _breakpoints[loc] = bpsAtLoc = new List <DkmRuntimeBreakpoint>();
            }
            bpsAtLoc.Add(bp);
            WriteBreakpoints();
        }
Ejemplo n.º 11
0
        private static void InjectHelperDll(DkmProcess process)
        {
            var injectionData = process.GetDataItem <HelperDllInjectionDataHolder>();

            if (injectionData != null)
            {
                // Injection is already in progress.
                return;
            }

            injectionData = new HelperDllInjectionDataHolder();
            process.SetDataItem(DkmDataCreationDisposition.CreateNew, injectionData);

            var pyrtInfo = process.GetPythonRuntimeInfo();

            // Loading the helper is done via CreateRemoteThread(LoadLibrary), which is inherently asynchronous.
            // On the other hand, we will not handle breakpoints until it is loaded - they won't even be bound.
            // If any Python code is running in the meantime, this may cause us to skip breakpoints, which is
            // very surprising in the run (F5) scenario, as the user expects all preset breakpoints to be hit.
            // To fix that, we need block the Python interpreter loop until the helper is fully loaded.
            //
            // Pausing all threads is not a good way to do this, because one of the threads may be holding the
            // loader lock, which will prevent the helper from loading and result in a deadlock. So instead,
            // block at a known location at the beginning of PyInitialize_Ex, and only freeze the thread that
            // calls it - this is sufficient to prevent execution of Python code in run scenario before helper
            // is loaded.
            //
            // For attach-to-running-process scenario, we do nothing because the attach itself is inherently
            // asynchronous, and so there's no user expectation that breakpoints light up instantly.

            // If Python is already initialized, this is attach-to-running-process - don't block.
            var initialized = pyrtInfo.DLLs.Python.GetStaticVariable <Int32Proxy>(
                "initialized",
                GetPyInitializeObjectFile(pyrtInfo.LanguageVersion)
                );

            if (initialized.Read() == 0)
            {
                // When Py_InitializeEx is hit, suspend the thread.
                DkmRuntimeBreakpoint makePendingCallsBP = null;
                makePendingCallsBP = CreateRuntimeDllExportedFunctionBreakpoint(pyrtInfo.DLLs.Python, "Py_InitializeEx", (thread, frameBase, vFrame) => {
                    makePendingCallsBP.Close();
                    if (process.GetPythonRuntimeInstance() == null)
                    {
                        thread.Suspend(true);
                        injectionData.SuspendedThread = thread;
                    }
                });
                makePendingCallsBP.Enable();
            }

            // Inject the helper DLL; OnHelperDllInitialized will resume the thread once the DLL is loaded and initialized.
            DebugAttach.AttachDkm(process.LivePart.Id);
        }
Ejemplo n.º 12
0
    public static void VscxOnRuntimeBreakpointReceived(
        this DkmProcess process,
        DkmRuntimeBreakpoint bp,
        DkmThread thread,
        bool hasException,
        DkmEventDescriptorS eventDescriptor) {
      RuntimeBreakpointHandler handler = process.GetDataItem<RuntimeBreakpointHandler>();
      if (handler == null)
        return;

      handler.OnRuntimeBreakpointReceived(bp, thread, hasException, eventDescriptor);
    }
Ejemplo n.º 13
0
 public void OnRuntimeBreakpointReceived(
     DkmRuntimeBreakpoint bp,
     DkmThread thread,
     bool hasException,
     DkmEventDescriptorS eventDescriptor) {
   FunctionTraceDataItem traceDataItem = bp.GetDataItem<FunctionTraceDataItem>();
   if (traceDataItem != null && traceDataItem.Tracer != null) {
     if (bp.SourceId == Guids.Source.FunctionTraceEnter)
       traceDataItem.Tracer.OnEntryBreakpointHit(bp, thread, hasException);
     else if (bp.SourceId == Guids.Source.FunctionTraceExit)
       traceDataItem.Tracer.OnExitBreakpointHit(bp, thread, hasException);
   }
 }
Ejemplo n.º 14
0
            void IDkmRuntimeMonitorBreakpointHandler.EnableRuntimeBreakpoint(DkmRuntimeBreakpoint runtimeBreakpoint)
            {
                var instructionBreakpoint = (runtimeBreakpoint as DkmRuntimeInstructionBreakpoint);

                if (instructionBreakpoint != null)
                {
                    var nativeInstructionAddress = instructionBreakpoint.InstructionAddress as DkmNativeInstructionAddress;

                    if (nativeInstructionAddress == null)
                    {
                        Debug.WriteLine("Missing breakpoint address");
                        return;
                    }

                    ulong address = instructionBreakpoint.InstructionAddress.CPUInstructionPart.InstructionPointer;

                    byte[] prevValue = new byte[1];

                    if (runtimeBreakpoint.Process.ReadMemory(address, DkmReadMemoryFlags.ExecutableOnly, prevValue) == 0)
                    {
                        Debug.WriteLine("Failed to read current instruction");
                        return;
                    }

                    var breakpointData = DebugHelpers.GetOrCreateDataItem <NullcBreakpointDataItem>(runtimeBreakpoint);

                    breakpointData.instructionAddress = nativeInstructionAddress;
                    breakpointData.prevValue          = prevValue;

                    // Write an 'int 3' instruction
                    runtimeBreakpoint.Process.InvisibleWriteMemory(address, new byte[1] {
                        0xcc
                    });

                    // Remember locations of the active user breakpoint instructions, skip internal breakpoints used in stepper
                    if (runtimeBreakpoint.SourceId != DebugHelpers.NullcStepperBreakpointSourceId)
                    {
                        var processData = DebugHelpers.GetOrCreateDataItem <NullcRemoteProcessDataItem>(instructionBreakpoint.Process);

                        if (!processData.activeBreakpointLocations.Contains(address))
                        {
                            processData.activeBreakpointLocations.Add(address);
                        }
                    }

                    return;
                }

                Debug.WriteLine("Failed to enable the breakpoint");
            }
Ejemplo n.º 15
0
        public static void VscxOnRuntimeBreakpointReceived(
            this DkmProcess process,
            DkmRuntimeBreakpoint bp,
            DkmThread thread,
            bool hasException,
            DkmEventDescriptorS eventDescriptor)
        {
            RuntimeBreakpointHandler handler = process.GetDataItem <RuntimeBreakpointHandler>();

            if (handler == null)
            {
                return;
            }

            handler.OnRuntimeBreakpointReceived(bp, thread, hasException, eventDescriptor);
        }
Ejemplo n.º 16
0
        public void RemoveBreakpoint(DkmRuntimeBreakpoint bp)
        {
            var loc = bp.GetDataItem <SourceLocation>();

            if (!_breakpoints.TryGetValue(loc, out List <DkmRuntimeBreakpoint> bpsAtLoc))
            {
                return;
            }
            if (!bpsAtLoc.Remove(bp))
            {
                return;
            }
            if (bpsAtLoc.Count == 0)
            {
                _breakpoints.Remove(loc);
            }
            WriteBreakpoints();
        }
Ejemplo n.º 17
0
        public void OnRuntimeBreakpointReceived(
            DkmRuntimeBreakpoint bp,
            DkmThread thread,
            bool hasException,
            DkmEventDescriptorS eventDescriptor)
        {
            FunctionTraceDataItem traceDataItem = bp.GetDataItem <FunctionTraceDataItem>();

            if (traceDataItem != null && traceDataItem.Tracer != null)
            {
                if (bp.SourceId == Guids.Source.FunctionTraceEnter)
                {
                    traceDataItem.Tracer.OnEntryBreakpointHit(bp, thread, hasException);
                }
                else if (bp.SourceId == Guids.Source.FunctionTraceExit)
                {
                    traceDataItem.Tracer.OnExitBreakpointHit(bp, thread, hasException);
                }
            }
        }
        void IDkmRuntimeMonitorBreakpointHandler.TestRuntimeBreakpoint(DkmRuntimeBreakpoint runtimeBreakpoint)
        {
            var runtimeInstructionBreakpoint = runtimeBreakpoint as DkmRuntimeInstructionBreakpoint;

            if (runtimeInstructionBreakpoint != null)
            {
                var customInstructionAddress = runtimeInstructionBreakpoint.InstructionAddress as DkmCustomInstructionAddress;

                if (customInstructionAddress != null)
                {
                    LuaBreakpointAdditionalData additionalData = new LuaBreakpointAdditionalData();

                    additionalData.ReadFrom(customInstructionAddress.AdditionalData.ToArray());

                    if (additionalData.line == 0)
                    {
                        throw new Exception("Invalid instruction breakpoint location");
                    }
                }
            }
        }
Ejemplo n.º 19
0
    void IFunctionTracer.OnExitBreakpointHit(DkmRuntimeBreakpoint bp, DkmThread thread, bool hasException) {
      FunctionTraceEntryDataItem traceDataItem = bp.GetDataItem<FunctionTraceEntryDataItem>();

      if (OnFunctionExited != null) {
        DkmStackWalkFrame frame = thread.GetTopStackWalkFrame(bp.RuntimeInstance);
        StackFrameAnalyzer exitAnalyzer = null;
        if (traceDataItem != null) {
          DkmSystemInformationFlags systemInformationFlags = 
              frame.ModuleInstance.Process.SystemInformation.Flags;
          bool isTarget64Bit = systemInformationFlags.HasFlag(DkmSystemInformationFlags.Is64Bit);
          int pointerSize = (isTarget64Bit) ? 8 : 4;
          exitAnalyzer = new CachedFrameAnalyzer(
              frameAnalyzer.Parameters, 
              traceDataItem.EntryArgumentValues, 
              pointerSize);
        }
        OnFunctionExited(frame, exitAnalyzer);
      }

      // Since this was a one-shot breakpoint, it is unconditionally closed.
      bp.Close();
    }
Ejemplo n.º 20
0
 public void OnNativeBreakpointHit(DkmRuntimeBreakpoint nativeBP, DkmThread thread)
 {
     if (nativeBP == _onBreakpointHitBP)
     {
         OnBreakpointHit(thread);
     }
     else if (nativeBP == _onStepCompleteBP)
     {
         OnStepComplete(thread);
     }
     else if (nativeBP == _onStepFallThroughBP)
     {
         OnStepFallThrough(thread);
     }
     else if (nativeBP.SourceId == Guids.PythonStepTargetSourceGuid)
     {
         OnStepTargetBreakpoint(thread);
     }
     else
     {
         Debug.Fail("BreakpointManager notified about a native breakpoint that it didn't create.");
     }
 }
Ejemplo n.º 21
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();
                    }
                }
            }
Ejemplo n.º 22
0
 void IDkmRuntimeMonitorBreakpointHandler.TestRuntimeBreakpoint(DkmRuntimeBreakpoint runtimeBreakpoint)
 {
     // Don't undestand what is expected here, there is no return value and no completion handler
 }
        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();
                    }
                }
            }
        }
Ejemplo n.º 24
0
 void IDkmRuntimeBreakpointReceived.OnRuntimeBreakpointReceived(DkmRuntimeBreakpoint bp, DkmThread thread, bool hasException, DkmEventDescriptorS eventDescriptor)
 {
     DkmProcess process = bp.Process;
       process.VscxOnRuntimeBreakpointReceived(bp, thread, hasException, eventDescriptor);
 }
Ejemplo n.º 25
0
        void IDkmRuntimeBreakpointReceived.OnRuntimeBreakpointReceived(DkmRuntimeBreakpoint bp, DkmThread thread, bool hasException, DkmEventDescriptorS eventDescriptor)
        {
            DkmProcess process = bp.Process;

            process.VscxOnRuntimeBreakpointReceived(bp, thread, hasException, eventDescriptor);
        }