ghc-debug-client-0.1.0.0: src/GHC/Debug/Client.hs
{- | The main API for creating debuggers. For example, this API can be used
to connect to an instrumented process, query the GC roots and then decode
the first root up to depth 10 and displayed to the user.
@
main = withDebuggeeConnect "\/tmp\/ghc-debug" p1
p1 :: Debuggee -> IO ()
p1 e = do
pause e
g <- run e $ do
precacheBlocks
(r:_) <- gcRoots
buildHeapGraph (Just 10) r
putStrLn (ppHeapGraph (const "") h)
@
-}
module GHC.Debug.Client
( -- * Running/Connecting to a debuggee
Debuggee
, DebugM
, debuggeeRun
, debuggeeConnect
, debuggeeClose
, withDebuggeeRun
, withDebuggeeConnect
, socketDirectory
, snapshotRun
-- * Running DebugM
, run
, runTrace
, runAnalysis
-- * Pause/Resume
, pause
, fork
, pauseThen
, resume
, pausePoll
, withPause
-- * Basic Requests
, version
, gcRoots
, allBlocks
, getSourceInfo
, savedObjects
, precacheBlocks
, dereferenceClosure
, dereferenceClosures
, dereferenceStack
, dereferencePapPayload
, dereferenceConDesc
, dereferenceInfoTable
, Quadtraversable(..)
-- * Building a Heap Graph
, buildHeapGraph
, multiBuildHeapGraph
, HG.HeapGraph(..)
, HG.HeapGraphEntry(..)
-- * Printing a heap graph
, HG.ppHeapGraph
-- * Tracing
, traceWrite
, traceMsg
-- * Caching
, saveCache
, loadCache
-- * Types
, module GHC.Debug.Types.Closures
, SourceInformation(..)
, RawBlock(..)
, BlockPtr
, StackPtr
, ClosurePtr
, InfoTablePtr
, HG.StackHI
, HG.PapHI
, HG.HeapGraphIndex
) where
import GHC.Debug.Types
import GHC.Debug.Types.Closures
import GHC.Debug.Convention (socketDirectory)
import GHC.Debug.Client.Monad
import GHC.Debug.Client.Query
import qualified GHC.Debug.Types.Graph as HG
import Data.List.NonEmpty (NonEmpty)
derefFuncM :: HG.DerefFunction DebugM Size
derefFuncM c = do
c' <- dereferenceClosure c
quadtraverse dereferencePapPayload dereferenceConDesc dereferenceStack pure c'
-- | Build a heap graph starting from the given root. The first argument
-- controls how many levels to recurse. You nearly always want to set this
-- to a small number ~ 10, as otherwise you can easily run out of memory.
buildHeapGraph :: Maybe Int -> ClosurePtr -> DebugM (HG.HeapGraph Size)
buildHeapGraph = HG.buildHeapGraph derefFuncM
-- | Build a heap graph starting from multiple roots. The first argument
-- controls how many levels to recurse. You nearly always want to set this
-- value to a small number ~ 10 as otherwise you can easily run out of
-- memory.
multiBuildHeapGraph :: Maybe Int -> NonEmpty ClosurePtr -> DebugM (HG.HeapGraph Size)
multiBuildHeapGraph = HG.multiBuildHeapGraph derefFuncM
-- | Perform the given analysis whilst the debuggee is paused, then resume
-- and apply the continuation to the result.
runAnalysis :: DebugM a -> (a -> IO r) -> Debuggee -> IO r
runAnalysis a k e = do
pause e
r <- run e a
resume e
k r