summaryrefslogtreecommitdiff
path: root/libraries/ghci
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2018-07-16 19:58:31 -0400
committerBen Gamari <ben@smart-cactus.org>2018-07-16 19:59:08 -0400
commit3bdf0d01ff47977830ada30ce85f174098486e23 (patch)
treea7bcd3a6842b1cc793ce990e924d157a408f93f0 /libraries/ghci
parentc4b8e719effe9b420b1c5cec0194134a44b26823 (diff)
downloadhaskell-3bdf0d01ff47977830ada30ce85f174098486e23.tar.gz
Support the GHCi debugger with -fexternal-interpreter
* All the tests in tests/ghci.debugger now pass with -fexternal-interpreter. These tests are now run with the ghci-ext way in addition to the normal way so we won't break it in the future. * I removed all the unsafeCoerce# calls from RtClosureInspect. Yay! The main changes are: * New messages: GetClosure and Seq. GetClosure is a remote interface to GHC.Exts.Heap.getClosureData, which required Binary instances for various datatypes. Fortunately this wasn't too painful thanks to DeriveGeneric. * No cheating by unsafeCoercing values when printing them. Now we have to turn the Closure representation back into the native representation when printing Int, Float, Double, Integer and Char. Of these, Integer was the most painful - we now have a dependency on integer-gmp due to needing access to the representation. * Fixed a bug in rts/Heap.c - it was bogusly returning stack content as pointers for an AP_STACK closure. Test Plan: * `cd testsuite/tests/ghci.debugger && make` * validate Reviewers: bgamari, patrickdoc, nomeata, angerman, hvr, erikd, goldfire Subscribers: alpmestan, snowleopard, rwbarton, thomie, carter GHC Trac Issues: #13184 Differential Revision: https://phabricator.haskell.org/D4955
Diffstat (limited to 'libraries/ghci')
-rw-r--r--libraries/ghci/GHCi/Message.hs35
-rw-r--r--libraries/ghci/GHCi/Run.hs7
2 files changed, 40 insertions, 2 deletions
diff --git a/libraries/ghci/GHCi/Message.hs b/libraries/ghci/GHCi/Message.hs
index 3f0bad9888..9b6740cc51 100644
--- a/libraries/ghci/GHCi/Message.hs
+++ b/libraries/ghci/GHCi/Message.hs
@@ -43,6 +43,7 @@ import Data.Dynamic
import Data.Typeable (TypeRep)
import Data.IORef
import Data.Map (Map)
+import Foreign
import GHC.Generics
import GHC.Stack.CCS
import qualified Language.Haskell.TH as TH
@@ -202,6 +203,18 @@ data Message a where
-> [RemoteRef (TH.Q ())]
-> Message (QResult ())
+ -- | Remote interface to GHC.Exts.Heap.getClosureData. This is used by
+ -- the GHCi debugger to inspect values in the heap for :print and
+ -- type reconstruction.
+ GetClosure
+ :: HValueRef
+ -> Message (GenClosure HValueRef)
+
+ -- | Evaluate something. This is used to support :force in GHCi.
+ Seq
+ :: HValueRef
+ -> Message (EvalResult ())
+
deriving instance Show (Message a)
@@ -410,6 +423,22 @@ data QState = QState
}
instance Show QState where show _ = "<QState>"
+-- Orphan instances of Binary for Ptr / FunPtr by conversion to Word64.
+-- This is to support Binary StgInfoTable which includes these.
+instance Binary (Ptr a) where
+ put p = put (fromIntegral (ptrToWordPtr p) :: Word64)
+ get = (wordPtrToPtr . fromIntegral) <$> (get :: Get Word64)
+
+instance Binary (FunPtr a) where
+ put = put . castFunPtrToPtr
+ get = castPtrToFunPtr <$> get
+
+-- Binary instances to support the GetClosure message
+instance Binary StgInfoTable
+instance Binary ClosureType
+instance Binary PrimType
+instance Binary a => Binary (GenClosure a)
+
data Msg = forall a . (Binary a, Show a) => Msg (Message a)
getMessage :: Get Msg
@@ -450,7 +479,9 @@ getMessage = do
31 -> Msg <$> return StartTH
32 -> Msg <$> (RunModFinalizers <$> get <*> get)
33 -> Msg <$> (AddSptEntry <$> get <*> get)
- _ -> Msg <$> (RunTH <$> get <*> get <*> get <*> get)
+ 34 -> Msg <$> (RunTH <$> get <*> get <*> get <*> get)
+ 35 -> Msg <$> (GetClosure <$> get)
+ _ -> Msg <$> (Seq <$> get)
putMessage :: Message a -> Put
putMessage m = case m of
@@ -489,6 +520,8 @@ putMessage m = case m of
RunModFinalizers a b -> putWord8 32 >> put a >> put b
AddSptEntry a b -> putWord8 33 >> put a >> put b
RunTH st q loc ty -> putWord8 34 >> put st >> put q >> put loc >> put ty
+ GetClosure a -> putWord8 35 >> put a
+ Seq a -> putWord8 36 >> put a
-- -----------------------------------------------------------------------------
-- Reading/writing messages
diff --git a/libraries/ghci/GHCi/Run.hs b/libraries/ghci/GHCi/Run.hs
index 2988ec202a..8ec7659abe 100644
--- a/libraries/ghci/GHCi/Run.hs
+++ b/libraries/ghci/GHCi/Run.hs
@@ -31,8 +31,9 @@ import Data.Binary.Get
import Data.ByteString (ByteString)
import qualified Data.ByteString.Unsafe as B
import GHC.Exts
+import GHC.Exts.Heap
import GHC.Stack
-import Foreign
+import Foreign hiding (void)
import Foreign.C
import GHC.Conc.Sync
import GHC.IO hiding ( bracket )
@@ -86,6 +87,10 @@ run m = case m of
MkConInfoTable ptrs nptrs tag ptrtag desc ->
toRemotePtr <$> mkConInfoTable ptrs nptrs tag ptrtag desc
StartTH -> startTH
+ GetClosure ref -> do
+ clos <- getClosureData =<< localRef ref
+ mapM (\(Box x) -> mkRemoteRef (HValue x)) clos
+ Seq ref -> tryEval (void $ evaluate =<< localRef ref)
_other -> error "GHCi.Run.run"
evalStmt :: EvalOpts -> EvalExpr HValueRef -> IO (EvalStatus [HValueRef])