@@ -272,6 +272,24 @@ function maybe_reset_frame!(@nospecialize(recurse), frame::Frame, @nospecialize(
272
272
return frame, pc
273
273
end
274
274
275
+ # Unwind the stack until an exc is eventually caught, thereby
276
+ # returning the frame that caught the exception at the pc of the catch
277
+ # or rethrow the error
278
+ function unwind_exception (frame:: Frame , exc)
279
+ while frame != = nothing
280
+ if ! isempty (frame. framedata. exception_frames)
281
+ # Exception caught
282
+ frame. pc = frame. framedata. exception_frames[end ]
283
+ frame. framedata. last_exception[] = exc
284
+ return frame
285
+ end
286
+ # recycle(frame)
287
+ frame = caller (frame)
288
+ frame === nothing || (frame. callee = nothing )
289
+ end
290
+ rethrow (exc)
291
+ end
292
+
275
293
"""
276
294
ret = debug_command(recurse, frame, cmd, rootistoplevel=false)
277
295
ret = debug_command(frame, cmd, rootistoplevel=false)
@@ -294,40 +312,48 @@ or one of the 'advanced' commands
294
312
Unlike other commands, the default setting for `recurse` is `Compiled()`.
295
313
"""
296
314
function debug_command (@nospecialize (recurse), frame:: Frame , cmd:: AbstractString , rootistoplevel:: Bool = false )
297
- # ::Union{Val{:nc},Val{:n},Val{:se}},
298
- # Need try/catch
299
315
istoplevel = rootistoplevel && frame. caller === nothing
300
- cmd == " nc" && return maybe_reset_frame! (recurse, frame, next_call! (recurse, frame, istoplevel), rootistoplevel)
301
- cmd == " n" && return maybe_reset_frame! (recurse, frame, next_line! (recurse, frame, istoplevel), rootistoplevel)
302
316
if cmd == " si"
303
317
stmt = pc_expr (frame)
304
318
cmd = is_call (stmt) ? " s" : " se"
305
319
end
306
- cmd == " se" && return maybe_reset_frame! (recurse, frame, step_expr! (recurse, frame, istoplevel), rootistoplevel)
307
- enter_generated = false
308
- if cmd == " sg"
309
- enter_generated = true
310
- cmd = " s"
311
- end
312
- if cmd == " s"
313
- pc = maybe_next_call! (recurse, frame, istoplevel)
314
- (isa (pc, BreakpointRef) || pc === nothing ) && return maybe_reset_frame! (recurse, frame, pc, rootistoplevel)
315
- stmt0 = stmt = pc_expr (frame, pc)
316
- if isexpr (stmt, :(= ))
317
- stmt = stmt. args[2 ]
320
+ try
321
+ cmd == " nc" && return maybe_reset_frame! (recurse, frame, next_call! (recurse, frame, istoplevel), rootistoplevel)
322
+ cmd == " n" && return maybe_reset_frame! (recurse, frame, next_line! (recurse, frame, istoplevel), rootistoplevel)
323
+ cmd == " se" && return maybe_reset_frame! (recurse, frame, step_expr! (recurse, frame, istoplevel), rootistoplevel)
324
+
325
+ enter_generated = false
326
+ if cmd == " sg"
327
+ enter_generated = true
328
+ cmd = " s"
329
+ end
330
+ if cmd == " s"
331
+ pc = maybe_next_call! (recurse, frame, istoplevel)
332
+ (isa (pc, BreakpointRef) || pc === nothing ) && return maybe_reset_frame! (recurse, frame, pc, rootistoplevel)
333
+ stmt0 = stmt = pc_expr (frame, pc)
334
+ if isexpr (stmt, :(= ))
335
+ stmt = stmt. args[2 ]
336
+ end
337
+ ret = evaluate_call! (dummy_breakpoint, frame, stmt; enter_generated= enter_generated)
338
+ isa (ret, BreakpointRef) && return maybe_reset_frame! (recurse, frame, ret, rootistoplevel)
339
+ maybe_assign! (frame, stmt0, ret)
340
+ frame. pc = ret + 1
341
+ return frame, frame. pc
342
+ end
343
+ if cmd == " c"
344
+ r = root (frame)
345
+ ret = finish_stack! (recurse, r, rootistoplevel)
346
+ return isa (ret, BreakpointRef) ? (leaf (r), ret) : nothing
347
+ end
348
+ cmd == " finish" && return maybe_reset_frame! (recurse, frame, finish! (recurse, frame, istoplevel), rootistoplevel)
349
+ catch err
350
+ frame = unwind_exception (frame, err)
351
+ if cmd == " c"
352
+ return debug_command (recurse, frame, " c" , istoplevel)
353
+ else
354
+ return debug_command (recurse, frame, " nc" , istoplevel)
318
355
end
319
- ret = evaluate_call! (dummy_breakpoint, frame, stmt; enter_generated= enter_generated)
320
- isa (ret, BreakpointRef) && return maybe_reset_frame! (recurse, frame, ret, rootistoplevel)
321
- maybe_assign! (frame, stmt0, ret)
322
- frame. pc = ret + 1
323
- return frame, frame. pc
324
- end
325
- if cmd == " c"
326
- r = root (frame)
327
- ret = finish_stack! (recurse, r, rootistoplevel)
328
- return isa (ret, BreakpointRef) ? (leaf (r), ret) : nothing
329
356
end
330
- cmd == " finish" && return maybe_reset_frame! (recurse, frame, finish! (recurse, frame, istoplevel), rootistoplevel)
331
357
throw (ArgumentError (" command $cmd not recognized" ))
332
358
end
333
359
debug_command (frame:: Frame , cmd:: AbstractString , rootistoplevel:: Bool = false ) =
0 commit comments