summaryrefslogtreecommitdiff
path: root/compiler/GHC/Runtime/Heap/Inspect.hs
diff options
context:
space:
mode:
authorRoland Senn <rsx@bluewin.ch>2019-11-11 11:56:59 +0100
committerRoland Senn <rsx@bluewin.ch>2020-02-29 17:36:59 +0100
commit3979485bd97771373214c44d14b7830ba447ad23 (patch)
treeb596caf792f542f563b20d0a30746e9b89b4d95f /compiler/GHC/Runtime/Heap/Inspect.hs
parent04d30137771a6cf8a18fda1ced25f78d0b2eb204 (diff)
downloadhaskell-3979485bd97771373214c44d14b7830ba447ad23.tar.gz
Show breakpoint locations of breakpoints which were ignored during :force (#2950)
GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing.
Diffstat (limited to 'compiler/GHC/Runtime/Heap/Inspect.hs')
-rw-r--r--compiler/GHC/Runtime/Heap/Inspect.hs11
1 files changed, 9 insertions, 2 deletions
diff --git a/compiler/GHC/Runtime/Heap/Inspect.hs b/compiler/GHC/Runtime/Heap/Inspect.hs
index 7842afcc5d..c9905b5801 100644
--- a/compiler/GHC/Runtime/Heap/Inspect.hs
+++ b/compiler/GHC/Runtime/Heap/Inspect.hs
@@ -30,6 +30,7 @@ import GhcPrelude
import GHC.Runtime.Interpreter as GHCi
import GHCi.RemoteTypes
import GHC.Driver.Types
+import GHCi.Message ( fromSerializableException )
import DataCon
import Type
@@ -59,6 +60,7 @@ import Outputable as Ppr
import GHC.Char
import GHC.Exts.Heap
import GHC.Runtime.Heap.Layout ( roundUpTo )
+import GHC.IO (throwIO)
import Control.Monad
import Data.Maybe
@@ -717,8 +719,13 @@ cvObtainTerm hsc_env max_depth force old_ty hval = runTR hsc_env $ do
-- Thunks we may want to force
t | isThunk t && force -> do
traceTR (text "Forcing a " <> text (show (fmap (const ()) t)))
- liftIO $ GHCi.seqHValue hsc_env a
- go (pred max_depth) my_ty old_ty a
+ evalRslt <- liftIO $ GHCi.seqHValue hsc_env a
+ case evalRslt of -- #2950
+ EvalSuccess _ -> go (pred max_depth) my_ty old_ty a
+ EvalException ex -> do
+ -- Report the exception to the UI
+ traceTR $ text "Exception occured:" <+> text (show ex)
+ liftIO $ throwIO $ fromSerializableException ex
-- Blackholes are indirections iff the payload is not TSO or BLOCKING_QUEUE. If
-- the indirection is a TSO or BLOCKING_QUEUE, we return the BLACKHOLE itself as
-- the suspension so that entering it in GHCi will enter the BLACKHOLE instead