Skip to content

Commit cef5350

Browse files
authored
add a way to break on throw (#253)
1 parent 7deef44 commit cef5350

File tree

4 files changed

+20
-7
lines changed

4 files changed

+20
-7
lines changed

src/breakpoints.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,14 @@ Turn on automatic breakpoints when any of the conditions described in `states` o
136136
The supported states are:
137137
138138
- `:error`: trigger a breakpoint any time an uncaught exception is thrown
139+
- `:throw` : trigger a breakpoint any time a throw is executed (even if it will eventually be caught)
139140
"""
140141
function break_on(states::Vararg{Symbol})
141142
for state in states
142143
if state == :error
143144
break_on_error[] = true
145+
elseif state == :throw
146+
break_on_throw[] = true
144147
else
145148
throw(ArgumentError(string("unsupported state :", state)))
146149
end
@@ -157,6 +160,8 @@ function break_off(states::Vararg{Symbol})
157160
for state in states
158161
if state == :error
159162
break_on_error[] = false
163+
elseif state == :throw
164+
break_on_throw[] = false
160165
else
161166
throw(ArgumentError(string("unsupported state :", state)))
162167
end

src/interpret.jl

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -560,13 +560,8 @@ behaviors:
560560
function handle_err(@nospecialize(recurse), frame, err)
561561
data = frame.framedata
562562
err_will_be_thrown_to_top_level = isempty(data.exception_frames) && !data.caller_will_catch_err
563-
if break_on_error[]
564-
# See if the current frame or a frame in the stack will catch this exception,
565-
# otherwise this exception would have been thrown to the user and we should
566-
# return a breakpoint
567-
if err_will_be_thrown_to_top_level
568-
return BreakpointRef(frame.framecode, frame.pc, err)
569-
end
563+
if break_on_throw[] || (break_on_error[] && err_will_be_thrown_to_top_level)
564+
return BreakpointRef(frame.framecode, frame.pc, err)
570565
end
571566
if isempty(data.exception_frames)
572567
is_root_frame = frame.caller === nothing

src/types.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ end
1515
truecondition(frame) = true
1616
falsecondition(frame) = false
1717
const break_on_error = Ref(false)
18+
const break_on_throw = Ref(false)
1819

1920
"""
2021
BreakpointState(isactive=true, condition=JuliaInterpreter.truecondition)

test/breakpoints.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,18 @@ end
165165
v = JuliaInterpreter.finish_and_return!(frame)
166166
@test v isa ErrorException
167167
@test stacklength(frame) == 1
168+
169+
# Break on caught exception when enabled
170+
break_on(:throw)
171+
try
172+
frame = JuliaInterpreter.enter_call(f_exc_outer);
173+
v = JuliaInterpreter.finish_and_return!(frame)
174+
@test v isa BreakpointRef
175+
@test v.err isa ErrorException
176+
@test v.framecode.scope == @which error()
177+
finally
178+
break_off(:throw)
179+
end
168180
finally
169181
break_off(:error)
170182
end

0 commit comments

Comments
 (0)