예제 #1
0
        private int SetState(enum_BP_STATE state) {
            if (_state == enum_BP_STATE.BPS_ENABLED) {
                if (state == enum_BP_STATE.BPS_DISABLED || state == enum_BP_STATE.BPS_DELETED) {
                    if (DebugBreakpoint != null) {
                        DebugBreakpoint.BreakpointHit -= DebugBreakpoint_BreakpointHit;
                        if (Engine.IsConnected) {
                            if (Engine.IsProgramDestroyed) {
                                // If engine is shutting down, do not wait for the delete eval to complete, to avoid
                                // blocking debugger detach if a long-running operation is in progress. This way the
                                // engine can just report successful detach right away, and breakpoints are deleted
                                // later, but as soon as it's actually possible.
                                DebugBreakpoint.DeleteAsync().DoNotWait();
                            } else {
                                TaskExtensions.RunSynchronouslyOnUIThread(ct => DebugBreakpoint.DeleteAsync(ct));
                            }
                        }
                    }
                }
            } else {
                if (state == enum_BP_STATE.BPS_ENABLED) {
                    if (Engine.IsProgramDestroyed) {
                        // Do not allow enabling breakpoints when engine is shutting down.
                        return VSConstants.E_ABORT;
                    }

                    DebugBreakpoint = TaskExtensions.RunSynchronouslyOnUIThread(ct => Engine.Tracer.CreateBreakpointAsync(Location, ct));
                    DebugBreakpoint.BreakpointHit += DebugBreakpoint_BreakpointHit;
                }
            }

            _state = state;
            return VSConstants.S_OK;
        }
예제 #2
0
        /// <summary>
        /// Sets breakpoints for the current runspace.
        /// </summary>
        /// <remarks>
        /// This method clears any existing breakpoints.
        /// </remarks>
        /// <param name="initialBreakpoints"></param>
        public void SetBreakpoints(IEnumerable <ScriptBreakpoint> initialBreakpoints)
        {
            if (initialBreakpoints == null)
            {
                return;
            }

            Log.InfoFormat("ScriptDebugger: Initial Breakpoints: {0}", initialBreakpoints.Count());
            ClearBreakpoints();

            foreach (var bp in initialBreakpoints)
            {
                SetBreakpoint(bp);
                _breakpoints.Add(bp);

                enum_BP_STATE[] pState = new enum_BP_STATE[1];
                if (bp.GetState(pState) == VSConstants.S_OK)
                {
                    if (pState[0] == enum_BP_STATE.BPS_DISABLED)
                    {
                        EnableBreakpoint(bp, 0);  // Disable PS breakpoint
                    }
                }
            }
        }
        public void BindAndDelete()
        {
            var mockBreakpointLocations = MockBreakpoint(1);

            MockDocumentPosition(TEST_FILE_NAME, LINE_NUMBER, COLUMN_NUMBER);
            mockLldbBreakpoint.GetId().Returns(EXPECTED_ID);

            var mockBoundBreakpoint = Substitute.For <IBoundBreakpoint>();

            mockBoundBreakpointFactory.Create(pendingBreakpoint, mockBreakpointLocations[0],
                                              mockProgram, Guid.Empty).Returns(mockBoundBreakpoint);

            pendingBreakpoint.Bind();
            var result = pendingBreakpoint.Delete();

            PENDING_BP_STATE_INFO[] state = new PENDING_BP_STATE_INFO[1];
            pendingBreakpoint.GetState(state);

            enum_BP_STATE[] bpState = new enum_BP_STATE[1];
            mockTarget.Received().BreakpointDelete(EXPECTED_ID);

            var boundBreakpoints = GetBoundBreakpoints();

            Assert.AreEqual(0, boundBreakpoints.Count);
            mockBoundBreakpoint.Received().Delete();

            Assert.AreEqual(VSConstants.S_OK, result);
        }
        public static enum_BP_STATE GetState(this IDebugBoundBreakpoint2 boundBreakpoint)
        {
            Contract.Requires <ArgumentNullException>(boundBreakpoint != null, "boundBreakpoint");

            enum_BP_STATE[] state = new enum_BP_STATE[1];
            ErrorHandler.ThrowOnFailure(boundBreakpoint.GetState(state));
            return(state[0]);
        }
        public static enum_BP_STATE GetState(this IDebugBoundBreakpoint2 boundBreakpoint)
        {
            Contract.Requires<ArgumentNullException>(boundBreakpoint != null, "boundBreakpoint");

            enum_BP_STATE[] state = new enum_BP_STATE[1];
            ErrorHandler.ThrowOnFailure(boundBreakpoint.GetState(state));
            return state[0];
        }
예제 #6
0
        int IDebugBoundBreakpoint2.Enable(int fEnable) {
            if (_state == enum_BP_STATE.BPS_DELETED) {
                Debug.Fail(Invariant($"Trying to enable or disable a deleted {nameof(AD7BoundBreakpoint)}"));
                return VSConstants.E_FAIL;
            }

            return SetState(_state = fEnable == 0 ? enum_BP_STATE.BPS_DISABLED : enum_BP_STATE.BPS_ENABLED);
        }
        public void Delete()
        {
            var result = boundBreakpoint.Delete();

            enum_BP_STATE[] state = new enum_BP_STATE[1];
            boundBreakpoint.GetState(state);

            Assert.AreEqual(enum_BP_STATE.BPS_DELETED, state[0]);
            Assert.AreEqual(VSConstants.S_OK, result);
        }
예제 #8
0
        int IDebugBoundBreakpoint2.Enable(int fEnable)
        {
            if (_state == enum_BP_STATE.BPS_DELETED)
            {
                Debug.Fail(Invariant($"Trying to enable or disable a deleted {nameof(AD7BoundBreakpoint)}"));
                return(VSConstants.E_FAIL);
            }

            return(SetState(_state = fEnable == 0 ? enum_BP_STATE.BPS_DISABLED : enum_BP_STATE.BPS_ENABLED));
        }
        public void Disable()
        {
            var result = boundBreakpoint.Enable(0);

            enum_BP_STATE[] state = new enum_BP_STATE[1];
            boundBreakpoint.GetState(state);

            Assert.AreEqual(enum_BP_STATE.BPS_DISABLED, state[0]);
            Assert.AreEqual(VSConstants.S_OK, result);
            mockBreakpointLocation.Received().SetEnabled(false);
        }
예제 #10
0
        // 
        int IDebugBoundBreakpoint2.GetState(enum_BP_STATE [] pState) {
            pState[0] = 0;

            if (_deleted) {
                pState[0] = enum_BP_STATE.BPS_DELETED;
            } else if (_enabled) {
                pState[0] = enum_BP_STATE.BPS_ENABLED;
            } else if (!_enabled) {
                pState[0] = enum_BP_STATE.BPS_DISABLED;
            }

            return VSConstants.S_OK;
        }
예제 #11
0
        private int SetState(enum_BP_STATE state)
        {
            if (_state == enum_BP_STATE.BPS_ENABLED)
            {
                if (state == enum_BP_STATE.BPS_DISABLED || state == enum_BP_STATE.BPS_DELETED)
                {
                    if (DebugBreakpoint != null)
                    {
                        DebugBreakpoint.BreakpointHit -= DebugBreakpoint_BreakpointHit;
                        if (Engine.IsConnected)
                        {
                            if (Engine.IsProgramDestroyed)
                            {
                                // If engine is shutting down, do not wait for the delete eval to complete, to avoid
                                // blocking debugger detach if a long-running operation is in progress. This way the
                                // engine can just report successful detach right away, and breakpoints are deleted
                                // later, but as soon as it's actually possible.
                                DebugBreakpoint.DeleteAsync()
                                .SilenceException <MessageTransportException>()
                                .SilenceException <RException>()
                                .DoNotWait();
                            }
                            else
                            {
                                TaskExtensions.RunSynchronouslyOnUIThread(ct => DebugBreakpoint.DeleteAsync(ct));
                            }
                        }
                    }
                }
            }
            else
            {
                if (state == enum_BP_STATE.BPS_ENABLED)
                {
                    if (Engine.IsProgramDestroyed)
                    {
                        // Do not allow enabling breakpoints when engine is shutting down.
                        return(VSConstants.E_ABORT);
                    }

                    DebugBreakpoint = TaskExtensions.RunSynchronouslyOnUIThread(ct => Engine.DebugSession.CreateBreakpointAsync(Location, ct));
                    DebugBreakpoint.BreakpointHit += DebugBreakpoint_BreakpointHit;
                }
            }

            _state = state;
            return(VSConstants.S_OK);
        }
예제 #12
0
 public int GetState(enum_BP_STATE[] pState)
 {
     pState[0] = 0;
     if (_pendingBreakpoint.Deleted)
     {
         pState[0] = enum_BP_STATE.BPS_DELETED;
     }
     else if (_pendingBreakpoint.Enabled)
     {
         pState[0] = enum_BP_STATE.BPS_ENABLED;
     }
     else if (!_pendingBreakpoint.Enabled)
     {
         pState[0] = enum_BP_STATE.BPS_DISABLED;
     }
     return VSConstants.S_OK;
 }
예제 #13
0
        int IDebugBoundBreakpoint2.GetState(enum_BP_STATE[] state)
        {
            if (mDeleted)
            {
                state[0] = enum_BP_STATE.BPS_DELETED;
            }
            else if (mEnabled)
            {
                state[0] = enum_BP_STATE.BPS_ENABLED;
            }
            else
            {
                state[0] = enum_BP_STATE.BPS_DISABLED;
            }

            return VSConstants.S_OK;
        }
예제 #14
0
 /// <summary>
 /// Gets the state of this bound breakpoint.
 /// </summary>
 /// <param name="pState">Returns a value from the BP_STATE enumeration that describes the state of the breakpoint.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public virtual int GetState( enum_BP_STATE[] pState )
 {
     Logger.Debug( string.Empty );
     return VSConstants.E_NOTIMPL;
 }
예제 #15
0
 public int GetState(enum_BP_STATE[] pState)
 {
     Log.Debug("ScriptBreakpoint: IDebugBoundBreakpoint2:GetState");
     pState[0] = enum_BP_STATE.BPS_ENABLED;
     return VSConstants.S_OK;
 }
예제 #16
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    private void OnClientAsyncRecord (MiAsyncRecord asyncRecord)
    {
      LoggingUtils.PrintFunction ();

      switch (asyncRecord.Type)
      {
        case MiAsyncRecord.AsyncType.Exec: 
        {
          // 
          // Records prefixed '*'.
          // 

          switch (asyncRecord.Class)
          {
            case "running":
            {
              // 
              // The target is now running. The thread field tells which specific thread is now running, can be 'all' if every thread is running.
              // 

              lock (NativeProgram)
              {
                NativeProgram.SetRunning (true);

                string threadId = asyncRecord ["thread-id"] [0].GetString ();

                if (threadId.Equals ("all"))
                {
                  Dictionary<uint, DebuggeeThread> programThreads = NativeProgram.GetThreads ();

                  lock (programThreads)
                  {
                    foreach (DebuggeeThread thread in programThreads.Values)
                    {
                      thread.SetRunning (true);
                    }
                  }
                }
                else
                {
                  uint numericThreadId = uint.Parse (threadId);

                  NativeProgram.CurrentThreadId = numericThreadId;

                  CLangDebuggeeThread thread = NativeProgram.GetThread (numericThreadId);

                  if (thread != null)
                  {
                    thread.SetRunning (true);
                  }
                }
              }

              break;
            }

            case "stopped":
            {
              // 
              // The target has stopped.
              // 

              CLangDebuggeeThread stoppedThread = null;

              lock (NativeProgram)
              {
                NativeProgram.SetRunning (false);

                if (asyncRecord.HasField ("thread-id"))
                {
                  uint threadId = asyncRecord ["thread-id"] [0].GetUnsignedInt ();

                  NativeProgram.CurrentThreadId = threadId;
                }

                if (stoppedThread == null)
                {
                  stoppedThread = NativeProgram.GetThread (NativeProgram.CurrentThreadId);
                }

                if (stoppedThread != null)
                {
                  stoppedThread.SetRunning (false);
                }
                else
                {
                  throw new InvalidOperationException ("Could not evaluate a thread on which we stopped");
                }

                // 
                // Flag some or all of the program's threads as stopped, directed by 'stopped-threads' field.
                // 

                bool hasStoppedThreads = asyncRecord.HasField ("stopped-threads");

                if (hasStoppedThreads)
                {
                  // 
                  // If all threads are stopped, the stopped field will have the value of "all". 
                  // Otherwise, the value of the stopped field will be a list of thread identifiers.
                  // 

                  MiResultValue stoppedThreadsRecord = asyncRecord ["stopped-threads"] [0];

                  if (stoppedThreadsRecord is MiResultValueList)
                  {
                    MiResultValueList stoppedThreads = stoppedThreadsRecord as MiResultValueList;

                    foreach (MiResultValue stoppedThreadValue in stoppedThreads.List)
                    {
                      uint stoppedThreadId = stoppedThreadValue.GetUnsignedInt ();

                      CLangDebuggeeThread thread = NativeProgram.GetThread (stoppedThreadId);

                      if (thread != null)
                      {
                        thread.SetRunning (false);
                      }
                    }
                  }
                  else
                  {
                    Dictionary<uint, DebuggeeThread> programThreads = NativeProgram.GetThreads ();

                    lock (programThreads)
                    {
                      foreach (DebuggeeThread thread in programThreads.Values)
                      {
                        thread.SetRunning (false);
                      }
                    }
                  }
                }
              }

              // 
              // Unblocks waiting for 'stopped' to be processed. Skipping event handling during interrupt requests as it confuses VS debugger flow.
              // 

              bool ignoreInterruptSignal = false;

              if (m_interruptOperationCompleted != null)
              {
                m_interruptOperationCompleted.Set ();

                ignoreInterruptSignal = true;
              }

              // 
              // Process any pending requests to refresh registered breakpoints.
              // 

#if false
              RefreshSharedLibraries ();
#endif


#if false
              NativeProgram.RefreshAllThreads ();
#endif

              if (!GdbClient.GetClientFeatureSupported ("breakpoint-notifications"))
              {
                Engine.BreakpointManager.RefreshBreakpoints ();
              }

              // 
              // This behaviour seems at odds with the GDB/MI spec, but a *stopped event can contain
              // multiple 'reason' fields. This seems to occur mainly when signals have been ignored prior 
              // to a non-ignored triggering, i.e:
              // 
              //   Signal        Stop\tPrint\tPass to program\tDescription\n
              //   SIGSEGV       No\tYes\tYes\t\tSegmentation fault\n
              // 
              // *stopped,reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",reason="exited-signalled",signal-name="SIGSEGV",signal-meaning="Segmentation fault"
              // 

              if (asyncRecord.HasField ("reason"))
              {
                // 
                // Here we pick the most recent (unhandled) signal.
                // 

                int stoppedIndex = asyncRecord ["reason"].Count - 1;

                MiResultValue stoppedReason = asyncRecord ["reason"] [stoppedIndex];

                // 
                // The reason field can have one of the following values:
                // 

                switch (stoppedReason.GetString ())
                {
                  case "breakpoint-hit":
                  case "watchpoint-trigger":
                  {
                    bool canContinue = true;

                    uint breakpointId = asyncRecord ["bkptno"] [0].GetUnsignedInt ();

                    string breakpointMode = asyncRecord ["disp"] [0].GetString ();

                    if (breakpointMode.Equals ("del"))
                    {
                      // 
                      // For temporary breakpoints, we won't have a valid managed object - so will just enforce a break event.
                      // 

                      //Engine.Broadcast (new DebugEngineEvent.Break (), NativeProgram.DebugProgram, stoppedThread);

                      Engine.Broadcast (new DebugEngineEvent.BreakpointHit (null), NativeProgram.DebugProgram, stoppedThread);
                    }
                    else
                    {
                      DebuggeeBreakpointBound boundBreakpoint = Engine.BreakpointManager.FindBoundBreakpoint (breakpointId);

                      if (boundBreakpoint == null)
                      {
                        // 
                        // Could not find the breakpoint we're looking for. Refresh everything and try again.
                        // 

                        Engine.BreakpointManager.SetDirty (true);

                        Engine.BreakpointManager.RefreshBreakpoints ();

                        boundBreakpoint = Engine.BreakpointManager.FindBoundBreakpoint (breakpointId);
                      }

                      if (boundBreakpoint == null)
                      {
                        // 
                        // Could not locate a registered breakpoint with matching id.
                        // 

                        DebugEngineEvent.Exception exception = new DebugEngineEvent.Exception (NativeProgram.DebugProgram, stoppedReason.GetString (), "Breakpoint #" + breakpointId + "hit", 0x00000000, canContinue);

                        Engine.Broadcast (exception, NativeProgram.DebugProgram, stoppedThread);
                      }
                      else
                      {
                        enum_BP_STATE [] breakpointState = new enum_BP_STATE [1];

                        LoggingUtils.RequireOk (boundBreakpoint.GetState (breakpointState));

                        if (breakpointState [0] == enum_BP_STATE.BPS_DELETED)
                        {
                          // 
                          // Hit a breakpoint which internally is flagged as deleted. Oh noes!
                          // 

                          DebugEngineEvent.Exception exception = new DebugEngineEvent.Exception (NativeProgram.DebugProgram, stoppedReason.GetString (), "Breakpoint #" + breakpointId + " hit [deleted]", 0x00000000, canContinue);

                          Engine.Broadcast (exception, NativeProgram.DebugProgram, stoppedThread);
                        }
                        else
                        {
                          // 
                          // Hit a breakpoint which is known about. Issue break event.
                          // 

                          IDebugBoundBreakpoint2 [] boundBreakpoints = new IDebugBoundBreakpoint2 [] { boundBreakpoint };

                          IEnumDebugBoundBreakpoints2 enumeratedBoundBreakpoint = new DebuggeeBreakpointBound.Enumerator (boundBreakpoints);

                          Engine.Broadcast (new DebugEngineEvent.BreakpointHit (enumeratedBoundBreakpoint), NativeProgram.DebugProgram, stoppedThread);
                        }
                      }
                    }

                    break;
                  }

                  case "end-stepping-range":
                  case "function-finished":
                  {
                    Engine.Broadcast (new DebugEngineEvent.StepComplete (), NativeProgram.DebugProgram, stoppedThread);

                    break;
                  }

                  case "signal-received":
                  {
                    string signalName = asyncRecord ["signal-name"] [stoppedIndex].GetString ();

                    string signalMeaning = asyncRecord ["signal-meaning"] [stoppedIndex].GetString ();

                    switch (signalName)
                    {
                      case null:
                      case "SIGINT":
                      {
                        if (!ignoreInterruptSignal)
                        {
                          Engine.Broadcast (new DebugEngineEvent.Break (), NativeProgram.DebugProgram, stoppedThread);
                        }

                        break;
                      }

                      default:
                      {
                        StringBuilder signalDescription = new StringBuilder ();

                        signalDescription.AppendFormat ("{0} ({1})", signalName, signalMeaning);

                        if (asyncRecord.HasField ("frame"))
                        {
                          MiResultValueTuple frameTuple = asyncRecord ["frame"] [0] as MiResultValueTuple;

                          if (frameTuple.HasField ("addr"))
                          {
                            string address = frameTuple ["addr"] [0].GetString ();

                            signalDescription.AppendFormat (" at {0}", address);
                          }

                          if (frameTuple.HasField ("func"))
                          {
                            string function = frameTuple ["func"] [0].GetString ();

                            signalDescription.AppendFormat (" ({0})", function);
                          }
                        }

                        bool canContinue = true;

                        DebugEngineEvent.Exception exception = new DebugEngineEvent.Exception (NativeProgram.DebugProgram, signalName, signalDescription.ToString (), 0x80000000, canContinue);

                        Engine.Broadcast (exception, NativeProgram.DebugProgram, stoppedThread);

                        break;
                      }
                    }

                    break;
                  }

                  case "read-watchpoint-trigger":
                  case "access-watchpoint-trigger":
                  case "location-reached":
                  case "watchpoint-scope":
                  case "solib-event":
                  case "fork":
                  case "vfork":
                  case "syscall-entry":
                  case "exec":
                  {
                    Engine.Broadcast (new DebugEngineEvent.Break (), NativeProgram.DebugProgram, stoppedThread);

                    break;
                  }

                  case "exited":
                  case "exited-normally":
                  case "exited-signalled":
                  {
                    // 
                    // React to program termination, but defer this so it doesn't consume the async output thread.
                    // 

                    ThreadPool.QueueUserWorkItem (delegate (object state)
                    {
                      try
                      {
                        LoggingUtils.RequireOk (Engine.Detach (NativeProgram.DebugProgram));
                      }
                      catch (Exception e)
                      {
                        LoggingUtils.HandleException (e);
                      }
                    });

                    break;
                  }
                }
              }

              break;
            }
          }

          break;
        }

        case MiAsyncRecord.AsyncType.Status:
        {
          // 
          // Records prefixed '+'.
          // 

          break;
        }


        case MiAsyncRecord.AsyncType.Notify:
        {
          // 
          // Records prefixed '='.
          // 

          switch (asyncRecord.Class)
          {
            case "thread-group-added":
            case "thread-group-started":
            {
              // 
              // A thread group became associated with a running program, either because the program was just started or the thread group was attached to a program.
              // 

              try
              {
                string threadGroupId = asyncRecord ["id"] [0].GetString ();

                m_threadGroupStatus [threadGroupId] = 0;
              }
              catch (Exception e)
              {
                LoggingUtils.HandleException (e);
              }

              break;
            }

            case "thread-group-removed":
            case "thread-group-exited":
            {
              // 
              // A thread group is no longer associated with a running program, either because the program has exited, or because it was detached from.
              // 

              try
              {
                string threadGroupId = asyncRecord ["id"] [0].GetString ();

                if (asyncRecord.HasField ("exit-code"))
                {
                  m_threadGroupStatus [threadGroupId] = asyncRecord ["exit-code"] [0].GetUnsignedInt ();
                }
              }
              catch (Exception e)
              {
                LoggingUtils.HandleException (e);
              }

              break;
            }

            case "thread-created":
            {
              // 
              // A thread either was created. The id field contains the gdb identifier of the thread. The gid field identifies the thread group this thread belongs to. 
              // 

              try
              {
                uint threadId = asyncRecord ["id"] [0].GetUnsignedInt ();

                string threadGroupId = asyncRecord ["group-id"] [0].GetString ();

                CLangDebuggeeThread thread = NativeProgram.GetThread (threadId);

                if (thread == null)
                {
                  NativeProgram.AddThread (threadId);
                }
              }
              catch (Exception e)
              {
                LoggingUtils.HandleException (e);
              }

              break;
            }

            case "thread-exited":
            {
              // 
              // A thread has exited. The 'id' field contains the GDB identifier of the thread. The 'group-id' field identifies the thread group this thread belongs to. 
              // 

              try
              {
                uint threadId = asyncRecord ["id"] [0].GetUnsignedInt ();

                string threadGroupId = asyncRecord ["group-id"] [0].GetString ();

                uint exitCode = m_threadGroupStatus [threadGroupId];

                NativeProgram.RemoveThread (threadId, exitCode);
              }
              catch (Exception e)
              {
                LoggingUtils.HandleException (e);
              }

              break;
            }

            case "thread-selected":
            {
              // 
              // Informs that the selected thread was changed as result of the last command.
              // 

              try
              {
                uint threadId = asyncRecord ["id"] [0].GetUnsignedInt ();

                NativeProgram.CurrentThreadId = threadId;
              }
              catch (Exception e)
              {
                LoggingUtils.HandleException (e);
              }

              break;
            }

            case "library-loaded":
            {
              // 
              // Reports that a new library file was loaded by the program.
              // 

              try
              {
                string moduleName = asyncRecord ["id"] [0].GetString ();

                CLangDebuggeeModule module = NativeProgram.GetModule (moduleName);

                if (module == null)
                {
                  module = NativeProgram.AddModule (moduleName, asyncRecord);
                }

                if (!GdbClient.GetClientFeatureSupported ("breakpoint-notifications"))
                {
                  Engine.BreakpointManager.SetDirty (true);
                }
              }
              catch (Exception e)
              {
                LoggingUtils.HandleException (e);
              }

              break;
            }

            case "library-unloaded":
            {
              // 
              // Reports that a library was unloaded by the program.
              // 

              try
              {
                string moduleName = asyncRecord ["id"] [0].GetString ();

                NativeProgram.RemoveModule (moduleName);

                if (!GdbClient.GetClientFeatureSupported ("breakpoint-notifications"))
                {
                  Engine.BreakpointManager.SetDirty (true);
                }
              }
              catch (Exception e)
              {
                LoggingUtils.HandleException (e);
              }

              break;
            }

            case "breakpoint-created":
            case "breakpoint-modified":
            case "breakpoint-deleted":
            {
              try
              {
                IDebugPendingBreakpoint2 pendingBreakpoint = null;

                if (asyncRecord.HasField ("bkpt"))
                {
                  MiResultValue breakpointData = asyncRecord ["bkpt"] [0];

                  MiBreakpoint currentGdbBreakpoint = new MiBreakpoint (breakpointData.Values);

                  pendingBreakpoint = Engine.BreakpointManager.FindPendingBreakpoint (currentGdbBreakpoint.ID);

                  // If the breakpoint is unknown, this usually means it was bound externally to the IDE.
                  /*if (pendingBreakpoint == null)
                  {
                    // 
                    // CreatePendingBreakpoint always sets the dirty flag, so we need to reset this if it's handled immediately.
                    // 

                    DebugBreakpointRequest breakpointRequest = new DebugBreakpointRequest (currentGdbBreakpoint.Address);

                    LoggingUtils.RequireOk (Engine.BreakpointManager.CreatePendingBreakpoint (breakpointRequest, out pendingBreakpoint));
                  }*/
                }
                else if (asyncRecord.HasField ("id"))
                {
                  pendingBreakpoint = Engine.BreakpointManager.FindPendingBreakpoint (asyncRecord ["id"] [0].GetUnsignedInt ());
                }

                bool wasDirty = Engine.BreakpointManager.IsDirty ();

                if (pendingBreakpoint != null)
                {
                  DebuggeeBreakpointPending thisBreakpoint = pendingBreakpoint as DebuggeeBreakpointPending;

                  thisBreakpoint.RefreshBoundBreakpoints ();

                  thisBreakpoint.RefreshErrorBreakpoints ();
                }

                if (wasDirty)
                {
                  Engine.BreakpointManager.SetDirty (true);
                }
              }
              catch (Exception e)
              {
                LoggingUtils.HandleException (e);
              }

              break;
            }
          }

          break;
        }
      }
    }
 int IDebugBoundBreakpoint2.GetState(enum_BP_STATE[] pState)
 {
   Debug.WriteLine("AD7Breakpoint: GetState");
   pState[0] = enum_BP_STATE.BPS_ENABLED;
   return VSConstants.S_OK;
 }
예제 #18
0
 int IDebugBoundBreakpoint2.GetState(enum_BP_STATE[] pState) {
     pState[0] = _state;
     return VSConstants.S_OK;
 }