private void ContinueExecution(MeadowDebugAdapterThreadState threadState, DesiredControlFlow controlFlowAction = DesiredControlFlow.Continue, int stepsPriorToAction = 0) { // Unlink our data for our thread id. ReferenceContainer.UnlinkThreadId(threadState.ThreadId); // Create a variable to track if we have finished stepping through the execution. bool finishedExecution = false; // Determine the direction to take steps prior to any evaluation. if (stepsPriorToAction >= 0) { // Loop for each step to take forward. for (int i = 0; i < stepsPriorToAction; i++) { // Take a step forward, if we could not, we finished execution, so we can stop looping. if (!threadState.IncrementStep()) { finishedExecution = true; break; } } } else { // Loop for each step to take backward for (int i = 0; i > stepsPriorToAction; i--) { // Take a step backward, if we could not, we can stop early as we won't be able to step backwards anymore. if (!threadState.DecrementStep()) { break; } } } // If we haven't finished execution, if (!finishedExecution) { switch (controlFlowAction) { case DesiredControlFlow.StepOver: // TODO: Implement case DesiredControlFlow.StepInto: { // Increment our step finishedExecution = !threadState.IncrementStep(); // If we stepped successfully, we evaluate, and if an event is encountered, we stop. if (!finishedExecution && EvaluateCurrentStep(threadState)) { return; } // Signal our breakpoint event has occurred for this thread. Protocol.SendEvent(new StoppedEvent(StoppedEvent.ReasonValue.Step) { ThreadId = threadState.ThreadId }); break; } case DesiredControlFlow.StepOut: // TODO: Implement case DesiredControlFlow.StepBackwards: { // Decrement our step bool decrementedStep = threadState.DecrementStep(); // If we stepped successfully, we evaluate, and if an event is encountered, we stop. if (decrementedStep && EvaluateCurrentStep(threadState)) { return; } // Signal our breakpoint event has occurred for this thread. Protocol.SendEvent(new StoppedEvent(StoppedEvent.ReasonValue.Step) { ThreadId = threadState.ThreadId }); // TODO: Check if we couldn't decrement step. Disable step backward if we can. break; } case DesiredControlFlow.Continue: { // Process the execution trace analysis while (threadState.CurrentStepIndex.HasValue && !Exiting) { // If we encountered an event at this point, stop if (EvaluateCurrentStep(threadState)) { return; } // If we couldn't step forward, this trace has been fully processed. if (!threadState.IncrementStep()) { break; } } // If we exited this way, our execution has concluded because we could not step any further (or there were never any steps). finishedExecution = true; break; } } } // If we finished execution, signal our thread if (finishedExecution) { threadState.Semaphore.Release(); } }
private void ContinueExecution(MeadowDebugAdapterThreadState threadState, DesiredControlFlow controlFlow = DesiredControlFlow.Continue) { // Unlink our data for our thread id. ReferenceContainer.UnlinkThreadId(threadState.ThreadId); // Verify we don't have an exception at this point that we haven't already handled, if we do, break out. if (threadState.LastExceptionTraceIndex != threadState.CurrentStepIndex && HandleExceptions(threadState)) { return; } // Determine how to continue execution. bool finishedExecution = false; switch (controlFlow) { case DesiredControlFlow.StepOver: // TODO: Implement case DesiredControlFlow.StepInto: { // Increment our step finishedExecution = !threadState.IncrementStep(); // Signal our breakpoint event has occurred for this thread. Protocol.SendEvent(new StoppedEvent(StoppedEvent.ReasonValue.Step) { ThreadId = threadState.ThreadId }); break; } case DesiredControlFlow.StepOut: // TODO: Implement case DesiredControlFlow.StepBackwards: { // Decrement our step threadState.DecrementStep(); // Signal our breakpoint event has occurred for this thread. Protocol.SendEvent(new StoppedEvent(StoppedEvent.ReasonValue.Step) { ThreadId = threadState.ThreadId }); // TODO: Check if we couldn't decrement step. Disable step backward if we can. break; } case DesiredControlFlow.Continue: { // Process the execution trace analysis while (threadState.CurrentStepIndex.HasValue) { // Obtain our breakpoints. bool hitBreakpoint = CheckBreakpointExists(threadState); // If we hit a breakpoint, we can signal our breakpoint and exit this execution method. if (hitBreakpoint) { // Signal our breakpoint event has occurred for this thread. Protocol.SendEvent(new StoppedEvent(StoppedEvent.ReasonValue.Breakpoint) { ThreadId = threadState.ThreadId }); return; } // Increment our position bool successfulStep = threadState.IncrementStep(); // If we couldn't step, break out of our loop if (!successfulStep) { break; } } // If we exited this way, our execution has concluded because we could not step any further (or there were never any steps). finishedExecution = true; break; } } // If we finished execution, signal our thread if (finishedExecution) { threadState.Semaphore.Release(); } }