public async Task <BreakResponse> Break() { await BeginRunStateTransition(); var fbb = BeginRequest(); BreakRequest.StartBreakRequest(fbb); int requestDataOffset = BreakRequest.EndBreakRequest(fbb); var response = await CommitRequest(fbb, RequestData.BreakRequest, requestDataOffset); System.Diagnostics.Debug.Assert(response.ResponseDataType == ResponseData.BreakResponse); var breakResponse = new BreakResponse(); response.GetResponseData(breakResponse); await CompleteRunStateTransition(RunState.Paused); return(breakResponse); }
private async Task HandleBreakModeEvent(ResultEventArgs results, BreakRequest breakRequest) { string reason = results.Results.TryFindString("reason"); int tid; if (!results.Results.Contains("thread-id")) { Results res = await MICommandFactory.ThreadInfo(); tid = res.FindInt("id"); } else { tid = results.Results.FindInt("thread-id"); } if (_childProcessHandler != null && await _childProcessHandler.Stopped(results.Results, tid)) { return; } // Any existing variable objects at this point are from the last time we were in break mode, and are // therefore invalid. Dispose them so they're marked for cleanup. lock (this.ActiveVariables) { foreach (IVariableInformation varInfo in this.ActiveVariables) { varInfo.Dispose(); } this.ActiveVariables.Clear(); } ThreadCache.MarkDirty(); MICommandFactory.DefineCurrentThread(tid); DebuggedThread thread = await ThreadCache.GetThread(tid); if (thread == null) { if (!this.IsStopDebuggingInProgress) { Debug.Fail("Failed to find thread on break event."); throw new Exception(String.Format(CultureInfo.CurrentUICulture, ResourceStrings.MissingThreadBreakEvent, tid)); } else { // It's possible that the SIGINT was sent because GDB is trying to terminate a running debuggee and stop debugging // See https://devdiv.visualstudio.com/DevDiv/VS%20Diag%20IntelliTrace/_workItems?_a=edit&id=236275&triage=true // for a repro return; } } await ThreadCache.StackFrames(thread); // prepopulate the break thread in the thread cache ThreadContext cxt = await ThreadCache.GetThreadContext(thread); if (cxt == null) { // Something went seriously wrong. For instance, this can happen when the primary thread // of an app exits on linux while background threads continue to run with pthread_exit on the main thread // See https://devdiv.visualstudio.com/DefaultCollection/DevDiv/VS%20Diag%20IntelliTrace/_workItems?_a=edit&id=197616&triage=true // for a repro Debug.Fail("Failed to find thread on break event."); throw new Exception(String.Format(CultureInfo.CurrentUICulture, ResourceStrings.MissingThreadBreakEvent, tid)); } ThreadCache.SendThreadEvents(this, null); // make sure that new threads have been pushed to the UI //always delete breakpoints pending deletion on break mode //the flag tells us if we hit an existing breakpoint pending deletion that we need to continue await _breakpointManager.DeleteBreakpointsPendingDeletion(); // Delete GDB variable objects that have been marked for cleanup List<string> variablesToDelete = null; lock (VariablesToDelete) { variablesToDelete = new List<string>(this.VariablesToDelete); VariablesToDelete.Clear(); } foreach (var variable in variablesToDelete) { try { await MICommandFactory.VarDelete(variable); } catch (MIException) { //not much to do really, we're leaking MI debugger variables. Debug.Fail("Failed to delete variable: " + variable + ". This is leaking memory in the MI Debugger."); } } if (String.IsNullOrWhiteSpace(reason) && !this.EntrypointHit) { breakRequest = BreakRequest.None; // don't let stopping interfere with launch processing this.EntrypointHit = true; CmdContinueAsync(); FireDeviceAppLauncherResume(); } else if (reason == "entry-point-hit") { this.EntrypointHit = true; _callback.OnEntryPoint(thread); } else if (reason == "breakpoint-hit") { string bkptno = results.Results.FindString("bkptno"); ulong addr = cxt.pc ?? 0; bool fContinue; TupleValue frame = results.Results.TryFind<TupleValue>("frame"); AD7BoundBreakpoint[] bkpt = _breakpointManager.FindHitBreakpoints(bkptno, addr, frame, out fContinue); if (bkpt != null) { if (frame != null && addr != 0) { string sourceFile = frame.TryFindString("fullname"); if (!String.IsNullOrEmpty(sourceFile)) { await this.VerifySourceFileTimestamp(addr, sourceFile); } } // Hitting a bp before the entrypoint overrules entrypoint processing. this.EntrypointHit = true; List<object> bplist = new List<object>(); bplist.AddRange(bkpt); _callback.OnBreakpoint(thread, bplist.AsReadOnly()); } else if (!this.EntrypointHit) { this.EntrypointHit = true; if (this.MICommandFactory.Mode == MIMode.Lldb) { // When the terminal window is closed, a SIGHUP is sent to lldb-mi and LLDB's default is to stop. // We want to not stop (break) when this happens and the SIGHUP to be sent to the debuggee process. // LLDB requires this command to be issued after the process has started. await ConsoleCmdAsync("process handle --pass true --stop false --notify false SIGHUP", true); } _callback.OnEntryPoint(thread); } else if (bkptno == "<EMBEDDED>") { _callback.OnBreakpoint(thread, new ReadOnlyCollection<object>(new AD7BoundBreakpoint[] { })); } else { if (fContinue) { //we hit a bp pending deletion //post the CmdContinueAsync operation so it does not happen until we have deleted all the pending deletes CmdContinueAsyncConditional(breakRequest); } else { // not one of our breakpoints, so stop with a message _callback.OnException(thread, "Unknown breakpoint", "", 0); } } } else if (reason == "watchpoint-trigger") { var wpt = results.Results.Find("wpt"); string bkptno = wpt.FindString("number"); ulong addr = cxt.pc ?? 0; bool fContinue; AD7BoundBreakpoint bkpt = _breakpointManager.FindHitWatchpoint(bkptno, out fContinue); if (bkpt != null) { List<object> bplist = new List<object>(); bplist.Add(bkpt); _callback.OnBreakpoint(thread, bplist.AsReadOnly()); } else { if (fContinue) { //we hit a bp pending deletion //post the CmdContinueAsync operation so it does not happen until we have deleted all the pending deletes CmdContinueAsyncConditional(breakRequest); } else { // not one of our breakpoints, so stop with a message _callback.OnException(thread, "Unknown watchpoint", "", 0); } } } else if (reason == "end-stepping-range" || reason == "function-finished") { _callback.OnStepComplete(thread); } else if (reason == "signal-received") { string name = results.Results.TryFindString("signal-name"); if ((name == "SIG32") || (name == "SIG33")) { // we are going to ignore these (Sigma) signals for now CmdContinueAsyncConditional(breakRequest); } else if (MICommandFactory.IsAsyncBreakSignal(results.Results)) { _callback.OnAsyncBreakComplete(thread); } else { uint code = 0; string sigName = results.Results.TryFindString("signal-name"); code = results.Results.Contains("signal") ? results.Results.FindUint("signal") : 0; if (String.IsNullOrEmpty(sigName) && code != 0 && EngineUtils.SignalMap.Instance.ContainsValue(code)) { sigName = EngineUtils.SignalMap.Instance.First((p) => p.Value == code).Key; } else if (!String.IsNullOrEmpty(sigName) && code == 0 && EngineUtils.SignalMap.Instance.ContainsKey(sigName)) { code = EngineUtils.SignalMap.Instance[sigName]; } bool stoppedAtSIGSTOP = false; if (sigName == "SIGSTOP") { if (AD7Engine.RemoveChildProcess(_launchOptions.ProcessId)) { stoppedAtSIGSTOP = true; } } string message = results.Results.TryFindString("signal-meaning"); if (stoppedAtSIGSTOP) { await MICommandFactory.Signal("SIGCONT"); } else { _callback.OnException(thread, sigName, message, code); } } } else if (reason == "exception-received") { string exceptionName = results.Results.TryFindString("exception-name"); if (string.IsNullOrEmpty(exceptionName)) exceptionName = "Exception"; string description = results.Results.FindString("exception"); Guid? exceptionCategory; ExceptionBreakpointState state; MICommandFactory.DecodeExceptionReceivedProperties(results.Results, out exceptionCategory, out state); _callback.OnException(thread, exceptionName, description, 0, exceptionCategory, state); } else { if (breakRequest == BreakRequest.None) { Debug.Fail("Unknown stopping reason"); _callback.OnException(thread, "Unknown", "Unknown stopping event", 0); } } if (IsExternalBreakRequest(breakRequest)) { _callback.OnStopComplete(thread); } }
private void CmdContinueAsyncConditional(BreakRequest request) { if (!IsExternalBreakRequest(request)) { CmdContinueAsync(); } }
private static bool IsExternalBreakRequest(BreakRequest breakRequest) { return breakRequest == BreakRequest.Async || breakRequest == BreakRequest.Stop; }
private void CmdContinueAsyncConditional(BreakRequest request) { if (request != BreakRequest.None) { CmdContinueAsync(); } }
public Task CmdBreak(BreakRequest request) { if (request > _requestingRealAsyncBreak) { _requestingRealAsyncBreak = request; } return CmdBreakInternal(); }
public StoppingEventArgs(Results results, BreakRequest asyncRequest = BreakRequest.None) : this(results, 0, asyncRequest) { }
public StoppingEventArgs(Results results, uint id, BreakRequest asyncRequest = BreakRequest.None) : base(results, id) { AsyncRequest = asyncRequest; }