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; }
/// <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]; }
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); }
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); }
// 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; }
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); }
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; }
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; }
/// <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; }
public int GetState(enum_BP_STATE[] pState) { Log.Debug("ScriptBreakpoint: IDebugBoundBreakpoint2:GetState"); pState[0] = enum_BP_STATE.BPS_ENABLED; return VSConstants.S_OK; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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; }
int IDebugBoundBreakpoint2.GetState(enum_BP_STATE[] pState) { pState[0] = _state; return VSConstants.S_OK; }