private bool DoDefineScope(DefineScopeArgs args, StringBuilder output) { SampleThread thread = this.GetThread(args.ThreadId); if (thread == null) { output.AppendLine(Invariant($"Error: Invalid thread id '{args.ThreadId}'!")); return(false); } SampleStackFrame frame = thread.GetTopStackFrame(); if (frame == null) { output.AppendLine(Invariant($"Error: Thread '{args.ThreadId}' has no stack frames!")); return(false); } if (frame.AllScopes.Any(s => String.Equals(s.Name, args.Name, StringComparison.OrdinalIgnoreCase))) { output.AppendLine(Invariant($"Error: Selected stack frame already has a scope called '{args.Name}'!")); return(false); } SampleScope scope = new SampleScope(this.adapter, args.Name, args.Expensive); frame.AddScope(scope); return(true); }
internal ScopesResponse HandleScopesRequest(ScopesArguments args) { SampleStackFrame frame = this.GetStackFrame(args.FrameId); if (frame == null) { throw new ProtocolException(Invariant($"Invalid frame id '{args.FrameId}'!")); } return(frame.HandleScopesRequest(args)); }
internal SetExpressionResponse HandleSetExpressionRequest(SetExpressionArguments args) { if (!args.FrameId.HasValue) { throw new ProtocolException("Evaluation without a frame id is not supported!"); } SampleStackFrame frame = this.GetStackFrame(args.FrameId.Value); if (frame == null) { throw new ProtocolException(Invariant($"Invalid frame id '{args.FrameId.Value}'!")); } return(frame.HandleSetExpressionRequest(args)); }
private void DebugThreadProc() { bool needsExtraIncrement = false; do { lock (this.syncObject) { if (!this.runEvent.WaitOne(0)) { // Waiting on the run event would have blocked, so send a stopped event before we wait for the event to be set if (!this.stopReason.HasValue) { throw new InvalidOperationException("Stopping for no reason!"); } this.Protocol.SendEvent(new StoppedEvent(reason: this.stopReason.Value, threadId: this.stopThreadId)); if (this.hyperStepSpeed != 0 && this.stopReason.Value == StoppedEvent.ReasonValue.Step) { // In hyper-step mode, we automatically continue and issue another step after each step this.ExitBreakCore(this.hyperStepSpeed, step: true); } this.stopReason = null; this.stopped = true; } } this.runEvent.WaitOne(); if (needsExtraIncrement) { this.currentLineNum++; needsExtraIncrement = false; } if (this.currentLineNum >= this.lines.Count) { // The "disconnect" request is handled by moving past the end of the list break; } // Process the current line string line = this.CurrentLine; if (line != null) { line = line.Trim(); if (!String.IsNullOrWhiteSpace(line)) { if (this.directiveProcessor.IsDirective(line)) { StringBuilder outputBuilder = new StringBuilder(); this.directiveProcessor.ProcessDirective(line, outputBuilder); this.SendOutput(outputBuilder.ToString()); } else if (line.StartsWith("#", StringComparison.Ordinal)) { // Comment, do nothing } else { // Not a directive, just send it as an output event this.SendOutput(line); } } } // If there's a pending exception, send a stopped event if (this.ExceptionManager.HasPendingException) { // When an exception is hit, we want to stop on the line that threw the exception so things look right in the UI, // but if we don't move to the next line as we usually do, we'll just hit the throw again as soon as we continue. // To avoid this, set a flag to cause an extra increment the next time through the loop. needsExtraIncrement = true; this.RequestStop(StoppedEvent.ReasonValue.Exception, this.ExceptionManager.PendingExceptionThread); continue; } // Move to the next line this.currentLineNum++; // Update top stack frame SampleStackFrame currentFrame = this.defaultThread.GetTopStackFrame(); currentFrame.Line = this.LineToClient(this.currentLineNum); // If a breakpoint is encountered, send a stopped event if (this.BreakpointManager.HasLineBreakpoint(this.currentLineNum)) { this.RequestStop(StoppedEvent.ReasonValue.Breakpoint); continue; } // If this is a step, stop on the next non-comment line with text if (this.stopReason == StoppedEvent.ReasonValue.Step && this.currentLineNum < this.lines.Count && this.CurrentLine != null && !this.CurrentLine.Trim().StartsWith("#", StringComparison.Ordinal)) { this.RequestStop(StoppedEvent.ReasonValue.Step); continue; } } while (this.currentLineNum < this.lines.Count); // If there are no more lines, end "debugging" this.ThreadManager.EndThread(this.defaultThread); this.Protocol.SendEvent(new ExitedEvent(exitCode: 0)); this.Protocol.SendEvent(new TerminatedEvent()); }
internal void PushStackFrame(SampleStackFrame frame) { this.frames.Push(frame); }