From a87c4b292cc7e412aefcdb66e72c97b5a2c9f1d6 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Wed, 16 May 2007 13:35:03 +0000 Subject: [PATCH] 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. --- rts/Exception.cmm | 52 +++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/rts/Exception.cmm b/rts/Exception.cmm index 15b2c64..ec56738 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. -- 1.7.10.4