@@ -128,79 +128,109 @@ public async Task ProcessExecutionTraceAnalysis(ExecutionTraceAnalysis traceAnal
128
128
_processTraceSemaphore . Release ( ) ;
129
129
}
130
130
131
- private void ContinueExecution ( MeadowDebugAdapterThreadState threadState , DesiredControlFlow controlFlow = DesiredControlFlow . Continue )
131
+ private void ContinueExecution ( MeadowDebugAdapterThreadState threadState , DesiredControlFlow controlFlowAction = DesiredControlFlow . Continue , int stepsPriorToAction = 0 )
132
132
{
133
133
// Unlink our data for our thread id.
134
134
ReferenceContainer . UnlinkThreadId ( threadState . ThreadId ) ;
135
135
136
- // Verify we don't have an exception at this point that we haven't already handled, if we do, break out.
137
- if ( threadState . LastExceptionTraceIndex != threadState . CurrentStepIndex && HandleExceptions ( threadState ) )
136
+ // Create a variable to track if we have finished stepping through the execution.
137
+ bool finishedExecution = false ;
138
+
139
+ // Determine the direction to take steps prior to any evaluation.
140
+ if ( stepsPriorToAction >= 0 )
138
141
{
139
- return ;
142
+ // Loop for each step to take forward.
143
+ for ( int i = 0 ; i < stepsPriorToAction ; i ++ )
144
+ {
145
+ // Take a step forward, if we could not, we finished execution, so we can stop looping.
146
+ if ( ! threadState . IncrementStep ( ) )
147
+ {
148
+ finishedExecution = true ;
149
+ break ;
150
+ }
151
+ }
140
152
}
141
-
142
- // Determine how to continue execution.
143
- bool finishedExecution = false ;
144
- switch ( controlFlow )
153
+ else
145
154
{
146
- case DesiredControlFlow . StepOver :
147
- // TODO: Implement
148
-
149
- case DesiredControlFlow . StepInto :
155
+ // Loop for each step to take backward
156
+ for ( int i = 0 ; i > stepsPriorToAction ; i -- )
157
+ {
158
+ // Take a step backward, if we could not, we can stop early as we won't be able to step backwards anymore.
159
+ if ( ! threadState . DecrementStep ( ) )
150
160
{
151
- // Increment our step
152
- finishedExecution = ! threadState . IncrementStep ( ) ;
153
-
154
- // Signal our breakpoint event has occurred for this thread.
155
- Protocol . SendEvent ( new StoppedEvent ( StoppedEvent . ReasonValue . Step ) { ThreadId = threadState . ThreadId } ) ;
156
161
break ;
157
162
}
163
+ }
164
+ }
158
165
159
- case DesiredControlFlow . StepOut :
160
- // TODO: Implement
166
+ // If we haven't finished execution,
167
+ if ( ! finishedExecution )
168
+ {
169
+ switch ( controlFlowAction )
170
+ {
171
+ case DesiredControlFlow . StepOver :
172
+ // TODO: Implement
161
173
162
- case DesiredControlFlow . StepBackwards :
163
- {
164
- // Decrement our step
165
- threadState . DecrementStep ( ) ;
174
+ case DesiredControlFlow . StepInto :
175
+ {
176
+ // Increment our step
177
+ finishedExecution = ! threadState . IncrementStep ( ) ;
166
178
167
- // Signal our breakpoint event has occurred for this thread.
168
- Protocol . SendEvent ( new StoppedEvent ( StoppedEvent . ReasonValue . Step ) { ThreadId = threadState . ThreadId } ) ;
179
+ // If we stepped successfully, we evaluate, and if an event is encountered, we stop.
180
+ if ( ! finishedExecution && EvaluateCurrentStep ( threadState ) )
181
+ {
182
+ return ;
183
+ }
169
184
170
- // TODO: Check if we couldn't decrement step. Disable step backward if we can.
171
- break ;
172
- }
185
+ // Signal our breakpoint event has occurred for this thread.
186
+ Protocol . SendEvent ( new StoppedEvent ( StoppedEvent . ReasonValue . Step ) { ThreadId = threadState . ThreadId } ) ;
187
+ break ;
188
+ }
173
189
174
- case DesiredControlFlow . Continue :
175
- {
176
- // Process the execution trace analysis
177
- while ( threadState . CurrentStepIndex . HasValue && ! Exiting )
190
+ case DesiredControlFlow . StepOut :
191
+ // TODO: Implement
192
+
193
+ case DesiredControlFlow . StepBackwards :
178
194
{
179
- // Obtain our breakpoints.
180
- bool hitBreakpoint = CheckBreakpointExists ( threadState ) ;
195
+ // Decrement our step
196
+ bool decrementedStep = threadState . DecrementStep ( ) ;
181
197
182
- // If we hit a breakpoint , we can signal our breakpoint and exit this execution method .
183
- if ( hitBreakpoint )
198
+ // If we stepped successfully , we evaluate, and if an event is encountered, we stop .
199
+ if ( decrementedStep && EvaluateCurrentStep ( threadState ) )
184
200
{
185
- // Signal our breakpoint event has occurred for this thread.
186
- Protocol . SendEvent ( new StoppedEvent ( StoppedEvent . ReasonValue . Breakpoint ) { ThreadId = threadState . ThreadId } ) ;
187
201
return ;
188
202
}
189
203
190
- // Increment our position
191
- bool successfulStep = threadState . IncrementStep ( ) ;
204
+ // Signal our breakpoint event has occurred for this thread.
205
+ Protocol . SendEvent ( new StoppedEvent ( StoppedEvent . ReasonValue . Step ) { ThreadId = threadState . ThreadId } ) ;
192
206
193
- // If we couldn't step, break out of our loop
194
- if ( ! successfulStep )
207
+ // TODO: Check if we couldn't decrement step. Disable step backward if we can.
208
+ break ;
209
+ }
210
+
211
+ case DesiredControlFlow . Continue :
212
+ {
213
+ // Process the execution trace analysis
214
+ while ( threadState . CurrentStepIndex . HasValue && ! Exiting )
195
215
{
196
- break ;
216
+ // If we encountered an event at this point, stop
217
+ if ( EvaluateCurrentStep ( threadState ) )
218
+ {
219
+ return ;
220
+ }
221
+
222
+ // If we couldn't step forward, this trace has been fully processed.
223
+ if ( ! threadState . IncrementStep ( ) )
224
+ {
225
+ break ;
226
+ }
197
227
}
198
- }
199
228
200
- // If we exited this way, our execution has concluded because we could not step any further (or there were never any steps).
201
- finishedExecution = true ;
202
- break ;
203
- }
229
+ // If we exited this way, our execution has concluded because we could not step any further (or there were never any steps).
230
+ finishedExecution = true ;
231
+ break ;
232
+ }
233
+ }
204
234
}
205
235
206
236
// If we finished execution, signal our thread
@@ -210,6 +240,12 @@ private void ContinueExecution(MeadowDebugAdapterThreadState threadState, Desire
210
240
}
211
241
}
212
242
243
+ private bool EvaluateCurrentStep ( MeadowDebugAdapterThreadState threadState , bool exceptions = true , bool breakpoints = true )
244
+ {
245
+ // Evaluate exceptions and breakpoints at this point in execution.
246
+ return ( exceptions && HandleExceptions ( threadState ) ) || ( breakpoints && HandleBreakpoint ( threadState ) ) ;
247
+ }
248
+
213
249
private bool HandleExceptions ( MeadowDebugAdapterThreadState threadState )
214
250
{
215
251
// Try to obtain an exception at this point
@@ -221,9 +257,6 @@ private bool HandleExceptions(MeadowDebugAdapterThreadState threadState)
221
257
// If we have an exception, throw it and return the appropriate status.
222
258
if ( traceException != null )
223
259
{
224
- // Set our last exception index.
225
- threadState . LastExceptionTraceIndex = threadState . CurrentStepIndex . Value ;
226
-
227
260
// Send our exception event.
228
261
var stoppedEvent = new StoppedEvent ( StoppedEvent . ReasonValue . Exception )
229
262
{
@@ -235,14 +268,11 @@ private bool HandleExceptions(MeadowDebugAdapterThreadState threadState)
235
268
}
236
269
}
237
270
238
- // If there was no exception, clear our last exception trace index
239
- threadState . LastExceptionTraceIndex = null ;
240
-
241
271
// We did not find an exception here, return false
242
272
return false ;
243
273
}
244
274
245
- private bool CheckBreakpointExists ( MeadowDebugAdapterThreadState threadState )
275
+ private bool HandleBreakpoint ( MeadowDebugAdapterThreadState threadState )
246
276
{
247
277
// Verify we have a valid step at this point.
248
278
if ( ! threadState . CurrentStepIndex . HasValue )
@@ -264,6 +294,8 @@ private bool CheckBreakpointExists(MeadowDebugAdapterThreadState threadState)
264
294
bool containsBreakpoint = success && breakpointLines . Any ( x => x == sourceLine . LineNumber ) ;
265
295
if ( containsBreakpoint )
266
296
{
297
+ // Signal our breakpoint event has occurred for this thread.
298
+ Protocol . SendEvent ( new StoppedEvent ( StoppedEvent . ReasonValue . Breakpoint ) { ThreadId = threadState . ThreadId } ) ;
267
299
return true ;
268
300
}
269
301
}
@@ -422,11 +454,11 @@ protected override void HandleContinueRequestAsync(IRequestResponder<ContinueArg
422
454
bool success = ThreadStates . TryGetValue ( responder . Arguments . ThreadId , out var threadState ) ;
423
455
if ( success )
424
456
{
425
- // Advance our step from our current position
426
- threadState . IncrementStep ( ) ;
427
-
428
- // Continue executing
429
- ContinueExecution ( threadState , DesiredControlFlow . Continue ) ;
457
+ // Continue executing, taking one step before continuing, as evaluation occurs before steps occur, and we want
458
+ // to ensure we advanced position from our last and don't re-evaluate the same trace point. We only do this on
459
+ // startup since we want the initial trace point to be evaluated. After that, we want to force advancement by
460
+ // at least one step before continuation/re-evaluation.
461
+ ContinueExecution ( threadState , DesiredControlFlow . Continue , 1 ) ;
430
462
}
431
463
}
432
464
0 commit comments