diff options
author | Simon Marlow <simonmar@microsoft.com> | 2007-05-16 13:35:03 +0000 |
---|---|---|
committer | Simon Marlow <simonmar@microsoft.com> | 2007-05-16 13:35:03 +0000 |
commit | a87c4b292cc7e412aefcdb66e72c97b5a2c9f1d6 (patch) | |
tree | c0c34073e694a29cc4f0e2cc109443f54e59837a /rts | |
parent | fe357baf4783cb5ab134037249835b3d77e2d001 (diff) | |
download | haskell-a87c4b292cc7e412aefcdb66e72c97b5a2c9f1d6.tar.gz |
raise#: break *after* stripping the stack, not before
This means that thunks under evaluation will have been updated with
the exception when we come to inspect them in GHCi. Blackholes are
much less friendly.
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Exception.cmm | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/rts/Exception.cmm b/rts/Exception.cmm index 15b2c64d4f..ec56738040 100644 --- a/rts/Exception.cmm +++ b/rts/Exception.cmm @@ -384,29 +384,6 @@ raisezh_fast } #endif - if (W_[no_break_on_exception] != 0) { - W_[no_break_on_exception] = 0; - } else { - if (TO_W_(CInt[rts_stop_on_exception]) != 0) { - W_ ioAction; - // we don't want any further exceptions to be caught, - // until GHCi is ready to handle them. This prevents - // deadlock if an exception is raised in InteractiveUI, - // for exmplae. Perhaps the stop_on_exception flag should - // be per-thread. - W_[rts_stop_on_exception] = 0; - "ptr" ioAction = foreign "C" deRefStablePtr (W_[rts_breakpoint_io_action] "ptr") []; - Sp = Sp - WDS(6); - Sp(5) = exception; - Sp(4) = stg_raise_ret_info; - Sp(3) = exception; // the AP_STACK - Sp(2) = base_GHCziBase_True_closure; // dummy breakpoint info - Sp(1) = base_GHCziBase_True_closure; // True <=> a breakpoint - R1 = ioAction; - jump stg_ap_pppv_info; - } - } - /* Inform the Hpc that an exception has been thrown */ foreign "C" hs_hpc_raise_event(CurrentTSO "ptr") []; @@ -451,6 +428,35 @@ retry_pop_stack: } } + // After stripping the stack, see whether we should break here for + // GHCi (c.f. the -fbreak-on-exception flag). We do this after + // stripping the stack for a reason: we'll be inspecting values in + // GHCi, and it helps if all the thunks under evaluation have + // already been updated with the exception, rather than being left + // as blackholes. + if (W_[no_break_on_exception] != 0) { + W_[no_break_on_exception] = 0; + } else { + if (TO_W_(CInt[rts_stop_on_exception]) != 0) { + W_ ioAction; + // we don't want any further exceptions to be caught, + // until GHCi is ready to handle them. This prevents + // deadlock if an exception is raised in InteractiveUI, + // for exmplae. Perhaps the stop_on_exception flag should + // be per-thread. + W_[rts_stop_on_exception] = 0; + "ptr" ioAction = foreign "C" deRefStablePtr (W_[rts_breakpoint_io_action] "ptr") []; + Sp = Sp - WDS(6); + Sp(5) = exception; + Sp(4) = stg_raise_ret_info; + Sp(3) = exception; // the AP_STACK + Sp(2) = base_GHCziBase_True_closure; // dummy breakpoint info + Sp(1) = base_GHCziBase_True_closure; // True <=> a breakpoint + R1 = ioAction; + jump stg_ap_pppv_info; + } + } + if (frame_type == STOP_FRAME) { /* * We've stripped the entire stack, the thread is now dead. |