diff --git a/src/breakpoints.jl b/src/breakpoints.jl index 1d22a14e..33268ff0 100644 --- a/src/breakpoints.jl +++ b/src/breakpoints.jl @@ -136,11 +136,14 @@ Turn on automatic breakpoints when any of the conditions described in `states` o The supported states are: - `:error`: trigger a breakpoint any time an uncaught exception is thrown +- `:throw` : trigger a breakpoint any time a throw is executed (even if it will eventually be caught) """ function break_on(states::Vararg{Symbol}) for state in states if state == :error break_on_error[] = true + elseif state == :throw + break_on_throw[] = true else throw(ArgumentError(string("unsupported state :", state))) end @@ -157,6 +160,8 @@ function break_off(states::Vararg{Symbol}) for state in states if state == :error break_on_error[] = false + elseif state == :throw + break_on_throw[] = false else throw(ArgumentError(string("unsupported state :", state))) end diff --git a/src/interpret.jl b/src/interpret.jl index 50f8ee48..d7a123de 100644 --- a/src/interpret.jl +++ b/src/interpret.jl @@ -560,13 +560,8 @@ behaviors: function handle_err(@nospecialize(recurse), frame, err) data = frame.framedata err_will_be_thrown_to_top_level = isempty(data.exception_frames) && !data.caller_will_catch_err - if break_on_error[] - # See if the current frame or a frame in the stack will catch this exception, - # otherwise this exception would have been thrown to the user and we should - # return a breakpoint - if err_will_be_thrown_to_top_level - return BreakpointRef(frame.framecode, frame.pc, err) - end + if break_on_throw[] || (break_on_error[] && err_will_be_thrown_to_top_level) + return BreakpointRef(frame.framecode, frame.pc, err) end if isempty(data.exception_frames) is_root_frame = frame.caller === nothing diff --git a/src/types.jl b/src/types.jl index b1122c9b..f3a3fceb 100644 --- a/src/types.jl +++ b/src/types.jl @@ -15,6 +15,7 @@ end truecondition(frame) = true falsecondition(frame) = false const break_on_error = Ref(false) +const break_on_throw = Ref(false) """ BreakpointState(isactive=true, condition=JuliaInterpreter.truecondition) diff --git a/test/breakpoints.jl b/test/breakpoints.jl index 102b53d7..d871f371 100644 --- a/test/breakpoints.jl +++ b/test/breakpoints.jl @@ -165,6 +165,18 @@ end v = JuliaInterpreter.finish_and_return!(frame) @test v isa ErrorException @test stacklength(frame) == 1 + + # Break on caught exception when enabled + break_on(:throw) + try + frame = JuliaInterpreter.enter_call(f_exc_outer); + v = JuliaInterpreter.finish_and_return!(frame) + @test v isa BreakpointRef + @test v.err isa ErrorException + @test v.framecode.scope == @which error() + finally + break_off(:throw) + end finally break_off(:error) end