{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DerivingVia #-}
module GHC.Debug.Client.Query
(
pause
, fork
, pauseThen
, resume
, pausePoll
, withPause
, precacheBlocks
, gcRoots
, allBlocks
, getSourceInfo
, savedObjects
, version
, dereferenceClosures
, dereferenceClosure
, dereferenceClosureDirect
, dereferenceClosureC
, dereferenceToClosurePtr
, addConstrDesc
, dereferenceStack
, dereferencePapPayload
, dereferenceConDesc
, dereferenceInfoTable
, dereferenceSRT
) where
import Control.Exception
import GHC.Debug.Types
import qualified GHC.Debug.Decode as D
import GHC.Debug.Decode.Stack
import GHC.Debug.Client.Monad
import GHC.Debug.Client.BlockCache
import Control.Monad.State
import Debug.Trace
pause :: Debuggee -> IO ()
pause :: Debuggee -> IO ()
pause Debuggee
e = do
forall a. Debuggee -> DebugM a -> IO a
run Debuggee
e forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (ForkOrPause -> Request ()
RequestPause ForkOrPause
Pause)
fork :: Debuggee -> IO ()
fork :: Debuggee -> IO ()
fork Debuggee
e = do
forall a. Debuggee -> DebugM a -> IO a
run Debuggee
e forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (ForkOrPause -> Request ()
RequestPause ForkOrPause
Fork)
resume :: Debuggee -> IO ()
resume :: Debuggee -> IO ()
resume Debuggee
e = forall a. Debuggee -> DebugM a -> IO a
run Debuggee
e forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request Request ()
RequestResume
pausePoll :: Debuggee -> IO ()
pausePoll :: Debuggee -> IO ()
pausePoll Debuggee
e = do
forall a. Debuggee -> DebugM a -> IO a
run Debuggee
e forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request Request ()
RequestPoll
withPause :: Debuggee -> IO a -> IO a
withPause :: forall a. Debuggee -> IO a -> IO a
withPause Debuggee
dbg IO a
act = forall a b c. IO a -> IO b -> IO c -> IO c
bracket_ (Debuggee -> IO ()
pause Debuggee
dbg) (Debuggee -> IO ()
resume Debuggee
dbg) IO a
act
lookupInfoTable :: RawClosure -> DebugM (StgInfoTableWithPtr, RawInfoTable, RawClosure)
lookupInfoTable :: RawClosure
-> DebugM (StgInfoTableWithPtr, RawInfoTable, RawClosure)
lookupInfoTable RawClosure
rc = do
let ptr :: ConstrDescCont
ptr = HasCallStack => RawClosure -> ConstrDescCont
getInfoTblPtr RawClosure
rc
(StgInfoTableWithPtr
itbl, RawInfoTable
rit) <- forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (ConstrDescCont -> Request (StgInfoTableWithPtr, RawInfoTable)
RequestInfoTable ConstrDescCont
ptr)
forall (m :: * -> *) a. Monad m => a -> m a
return (StgInfoTableWithPtr
itbl,RawInfoTable
rit, RawClosure
rc)
pauseThen :: Debuggee -> DebugM b -> IO b
pauseThen :: forall a. Debuggee -> DebugM a -> IO a
pauseThen Debuggee
e DebugM b
d =
Debuggee -> IO ()
pause Debuggee
e forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Debuggee -> DebugM a -> IO a
run Debuggee
e DebugM b
d
dereferenceClosureC :: ClosurePtr -> DebugM SizedClosureC
dereferenceClosureC :: ClosurePtr -> DebugM SizedClosureC
dereferenceClosureC ClosurePtr
cp = SizedClosure -> DebugM SizedClosureC
addConstrDesc forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ClosurePtr -> DebugM SizedClosure
dereferenceClosure ClosurePtr
cp
addConstrDesc :: SizedClosure -> DebugM SizedClosureC
addConstrDesc :: SizedClosure -> DebugM SizedClosureC
addConstrDesc SizedClosure
c =
forall (m :: * -> * -> * -> * -> * -> *) (f :: * -> *) a b c d e g
h i j k.
(Quintraversable m, Applicative f) =>
(a -> f b)
-> (c -> f d)
-> (e -> f g)
-> (h -> f i)
-> (j -> f k)
-> m a c e h j
-> f (m b d g i k)
quintraverse forall (f :: * -> *) a. Applicative f => a -> f a
pure forall (f :: * -> *) a. Applicative f => a -> f a
pure ConstrDescCont -> DebugM ConstrDesc
dereferenceConDesc forall (f :: * -> *) a. Applicative f => a -> f a
pure forall (f :: * -> *) a. Applicative f => a -> f a
pure SizedClosure
c
dereferenceToClosurePtr :: SizedClosure -> DebugM SizedClosureP
dereferenceToClosurePtr :: SizedClosure -> DebugM SizedClosureP
dereferenceToClosurePtr SizedClosure
c = do
forall (m :: * -> * -> * -> * -> * -> *) (f :: * -> *) a b c d e g
h i j k.
(Quintraversable m, Applicative f) =>
(a -> f b)
-> (c -> f d)
-> (e -> f g)
-> (h -> f i)
-> (j -> f k)
-> m a c e h j
-> f (m b d g i k)
quintraverse ConstrDescCont -> DebugM SrtPayload
dereferenceSRT PayloadCont -> DebugM PapPayload
dereferencePapPayload ConstrDescCont -> DebugM ConstrDesc
dereferenceConDesc forall (f :: * -> *) a. Applicative f => a -> f a
pure forall (f :: * -> *) a. Applicative f => a -> f a
pure SizedClosure
c
dereferenceClosureDirect :: ClosurePtr -> DebugM SizedClosure
dereferenceClosureDirect :: ClosurePtr -> DebugM SizedClosure
dereferenceClosureDirect ClosurePtr
c = do
RawClosure
raw_c <- forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (ClosurePtr -> Request RawClosure
RequestClosure ClosurePtr
c)
let it :: ConstrDescCont
it = HasCallStack => RawClosure -> ConstrDescCont
getInfoTblPtr RawClosure
raw_c
(StgInfoTableWithPtr, RawInfoTable)
raw_it <- forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (ConstrDescCont -> Request (StgInfoTableWithPtr, RawInfoTable)
RequestInfoTable ConstrDescCont
it)
(StgInfoTableWithPtr, RawInfoTable)
-> (ClosurePtr, RawClosure) -> DebugM SizedClosure
decodeClosure (StgInfoTableWithPtr, RawInfoTable)
raw_it (ClosurePtr
c, RawClosure
raw_c)
decodeClosure :: (StgInfoTableWithPtr, RawInfoTable)
-> (ClosurePtr, RawClosure)
-> DebugM SizedClosure
decodeClosure :: (StgInfoTableWithPtr, RawInfoTable)
-> (ClosurePtr, RawClosure) -> DebugM SizedClosure
decodeClosure (StgInfoTableWithPtr, RawInfoTable)
it (ClosurePtr, RawClosure)
c = do
Version
ver <- DebugM Version
version
return $ Version
-> (StgInfoTableWithPtr, RawInfoTable)
-> (ClosurePtr, RawClosure)
-> SizedClosure
D.decodeClosure Version
ver (StgInfoTableWithPtr, RawInfoTable)
it (ClosurePtr, RawClosure)
c
dereferenceClosures :: [ClosurePtr] -> DebugM [SizedClosure]
dereferenceClosures :: [ClosurePtr] -> DebugM [SizedClosure]
dereferenceClosures [ClosurePtr]
cs = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ClosurePtr -> DebugM SizedClosure
dereferenceClosure [ClosurePtr]
cs
dereferenceStack :: StackCont -> DebugM StackFrames
dereferenceStack :: StackCont -> DebugM StackFrames
dereferenceStack (StackCont StackPtr
sp RawStack
stack) = do
let get_bitmap :: Word32 -> DebugM PtrBitmap
get_bitmap Word32
o = forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (StackPtr -> Word32 -> Request PtrBitmap
RequestStackBitmap StackPtr
sp Word32
o)
get_info_table :: RawClosure -> DebugM StgInfoTableWithPtr
get_info_table RawClosure
rc = (\(StgInfoTableWithPtr
a, RawInfoTable
_, RawClosure
_) -> StgInfoTableWithPtr
a) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RawClosure
-> DebugM (StgInfoTableWithPtr, RawInfoTable, RawClosure)
lookupInfoTable RawClosure
rc
forall (m :: * -> *).
Monad m =>
(RawClosure -> m StgInfoTableWithPtr)
-> (Word32 -> m PtrBitmap) -> RawStack -> m StackFrames
decodeStack RawClosure -> DebugM StgInfoTableWithPtr
get_info_table Word32 -> DebugM PtrBitmap
get_bitmap RawStack
stack
dereferencePapPayload :: PayloadCont -> DebugM PapPayload
dereferencePapPayload :: PayloadCont -> DebugM PapPayload
dereferencePapPayload (PayloadCont ClosurePtr
fp [Word64]
raw) = do
PtrBitmap
bm <- forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (Word16 -> ClosurePtr -> Request PtrBitmap
RequestFunBitmap (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [Word64]
raw) ClosurePtr
fp)
return $ forall b. [FieldValue b] -> GenPapPayload b
GenPapPayload (forall s a. State s a -> s -> a
evalState (forall (m :: * -> *) a.
Monad m =>
(Bool -> m a) -> PtrBitmap -> m [a]
traversePtrBitmap Bool -> StateT [Word64] Identity (FieldValue ClosurePtr)
decodeField PtrBitmap
bm) [Word64]
raw)
where
getWord :: StateT [Word64] Identity Word64
getWord = do
Word64
v <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall a. [a] -> a
head
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a. [a] -> [a]
tail
return Word64
v
decodeField :: Bool -> StateT [Word64] Identity (FieldValue ClosurePtr)
decodeField Bool
True = forall b. b -> FieldValue b
SPtr forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> ClosurePtr
mkClosurePtr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT [Word64] Identity Word64
getWord
decodeField Bool
False = forall b. Word64 -> FieldValue b
SNonPtr forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT [Word64] Identity Word64
getWord
dereferenceConDesc :: ConstrDescCont -> DebugM ConstrDesc
dereferenceConDesc :: ConstrDescCont -> DebugM ConstrDesc
dereferenceConDesc ConstrDescCont
i = forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (ConstrDescCont -> Request ConstrDesc
RequestConstrDesc ConstrDescCont
i)
_noConDesc :: ConstrDescCont -> DebugM ConstrDesc
_noConDesc :: ConstrDescCont -> DebugM ConstrDesc
_noConDesc ConstrDescCont
c = forall a b. Show a => a -> b -> b
traceShow ConstrDescCont
c (forall (m :: * -> *) a. Monad m => a -> m a
return ConstrDesc
emptyConDesc)
emptyConDesc :: ConstrDesc
emptyConDesc :: ConstrDesc
emptyConDesc = [Char] -> [Char] -> [Char] -> ConstrDesc
ConstrDesc [Char]
"" [Char]
"" [Char]
""
dereferenceClosure :: ClosurePtr -> DebugM SizedClosure
dereferenceClosure :: ClosurePtr -> DebugM SizedClosure
dereferenceClosure ClosurePtr
cp
| Bool -> Bool
not (ClosurePtr -> Bool
heapAlloced ClosurePtr
cp) = ClosurePtr -> DebugM SizedClosure
dereferenceClosureDirect ClosurePtr
cp
| Bool
otherwise = do
RawClosure
rc <- forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
BlockCacheRequest resp -> m resp
requestBlock (ClosurePtr -> BlockCacheRequest RawClosure
LookupClosure ClosurePtr
cp)
if RawClosure -> Int
rawClosureSize RawClosure
rc forall a. Ord a => a -> a -> Bool
< Int
8
then do
SizedClosure
res <- ClosurePtr -> DebugM SizedClosure
dereferenceClosureDirect ClosurePtr
cp
forall a (f :: * -> *). (Show a, Applicative f) => a -> f ()
traceShowM ([Char]
"Warning!!: block decoding failed, report this as a bug:" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (ClosurePtr
cp, SizedClosure
res))
return SizedClosure
res
else do
let it :: ConstrDescCont
it = HasCallStack => RawClosure -> ConstrDescCont
getInfoTblPtr RawClosure
rc
(StgInfoTableWithPtr, RawInfoTable)
st_it <- forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (ConstrDescCont -> Request (StgInfoTableWithPtr, RawInfoTable)
RequestInfoTable ConstrDescCont
it)
(StgInfoTableWithPtr, RawInfoTable)
-> (ClosurePtr, RawClosure) -> DebugM SizedClosure
decodeClosure (StgInfoTableWithPtr, RawInfoTable)
st_it (ClosurePtr
cp, RawClosure
rc)
precacheBlocks :: DebugM [RawBlock]
precacheBlocks :: DebugM [RawBlock]
precacheBlocks = forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
BlockCacheRequest resp -> m resp
requestBlock BlockCacheRequest [RawBlock]
PopulateBlockCache
gcRoots :: DebugM [ClosurePtr]
gcRoots :: DebugM [ClosurePtr]
gcRoots = forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request Request [ClosurePtr]
RequestRoots
allBlocks :: DebugM [RawBlock]
allBlocks :: DebugM [RawBlock]
allBlocks = forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request Request [RawBlock]
RequestAllBlocks
getSourceInfo :: InfoTablePtr -> DebugM (Maybe SourceInformation)
getSourceInfo :: ConstrDescCont -> DebugM (Maybe SourceInformation)
getSourceInfo = forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConstrDescCont -> Request (Maybe SourceInformation)
RequestSourceInfo
savedObjects :: DebugM [ClosurePtr]
savedObjects :: DebugM [ClosurePtr]
savedObjects = forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request Request [ClosurePtr]
RequestSavedObjects
version :: DebugM Version
version :: DebugM Version
version = forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request Request Version
RequestVersion
dereferenceInfoTable :: InfoTablePtr -> DebugM StgInfoTable
dereferenceInfoTable :: ConstrDescCont -> DebugM StgInfoTable
dereferenceInfoTable ConstrDescCont
it = StgInfoTableWithPtr -> StgInfoTable
decodedTable forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (ConstrDescCont -> Request (StgInfoTableWithPtr, RawInfoTable)
RequestInfoTable ConstrDescCont
it)
dereferenceSRT :: InfoTablePtr -> DebugM SrtPayload
dereferenceSRT :: ConstrDescCont -> DebugM SrtPayload
dereferenceSRT ConstrDescCont
it = forall b. Maybe b -> GenSrtPayload b
GenSrtPayload forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) resp.
(DebugMonad m, Show resp, Typeable resp) =>
Request resp -> m resp
request (ConstrDescCont -> Request (Maybe ClosurePtr)
RequestSRT ConstrDescCont
it)