Skip to content

Commit 841423c

Browse files
authored
only unlink frames if exception will not be thrown to top level (#214)
* only unlink frames if exception will not be thrown to top level * Update src/interpret.jl Co-Authored-By: KristofferC <[email protected]> * put less in try
1 parent d6186c6 commit 841423c

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

src/interpret.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,16 +555,18 @@ behaviors:
555555
"""
556556
function handle_err(@nospecialize(recurse), frame, err)
557557
data = frame.framedata
558+
err_will_be_thrown_to_top_level = isempty(data.exception_frames) && !data.caller_will_catch_err
558559
if break_on_error[]
559560
# See if the current frame or a frame in the stack will catch this exception,
560561
# otherwise this exception would have been thrown to the user and we should
561562
# return a breakpoint
562-
if isempty(data.exception_frames) && !data.caller_will_catch_err
563+
if err_will_be_thrown_to_top_level
563564
return BreakpointRef(frame.framecode, frame.pc, err)
564565
end
565566
end
566567
if isempty(data.exception_frames)
567-
if frame.caller !== nothing
568+
is_root_frame = frame.caller === nothing
569+
if !is_root_frame && !err_will_be_thrown_to_top_level
568570
frame.caller.callee = nothing
569571
recycle(frame)
570572
end

test/debug.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ struct B{T} end
278278
g_inner() = error()
279279
fr = JuliaInterpreter.enter_call(f_outer)
280280
@test_throws ErrorException debug_command(fr, :finish)
281-
@test stacklength(fr) == 1
281+
@test stacklength(fr) == 3
282282

283283
# Break on error
284284
try
@@ -424,4 +424,21 @@ struct B{T} end
424424
frame, pc = debug_command(frame, :si)
425425
@test frame.pc == 1
426426
end
427+
428+
429+
@testset "preservation of stack when throwing to toplevel" begin
430+
f() = "αβ"[2]
431+
frame1 = JuliaInterpreter.enter_call(f);
432+
err = try debug_command(frame1, :c)
433+
catch err
434+
err
435+
end
436+
try
437+
break_on(:error)
438+
frame2, pc = @interpret f()
439+
@test leaf(frame2).framecode.scope === leaf(frame1).framecode.scope
440+
finally
441+
break_off(:error)
442+
end
443+
end
427444
# end

0 commit comments

Comments
 (0)