-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Useful functions for writing heap analysis tools which use -- ghc-debug. -- -- Useful functions for writing heap analysis tools which use ghc-debug. @package ghc-debug-client @version 0.6.0.0 module GHC.Debug.Client.BlockCache data BlockCache data BlockCacheRequest a [LookupClosure] :: ClosurePtr -> BlockCacheRequest RawClosure [PopulateBlockCache] :: BlockCacheRequest [RawBlock] handleBlockReq :: Tracer IO String -> (forall a. Request a -> IO a) -> IORef BlockCache -> BlockCacheRequest resp -> IO resp emptyBlockCache :: BlockCache bcSize :: BlockCache -> Int addBlocks :: [RawBlock] -> BlockCache -> BlockCache instance GHC.Show.Show (GHC.Debug.Client.BlockCache.BlockCacheRequest a) instance GHC.Classes.Eq (GHC.Debug.Client.BlockCache.BlockCacheRequest a) instance Data.Hashable.Class.Hashable (GHC.Debug.Client.BlockCache.BlockCacheRequest a) instance Data.Binary.Class.Binary GHC.Debug.Client.BlockCache.BlockCache module GHC.Debug.Client.Monad.Class class (MonadFail m, Monad m) => DebugMonad m where { type DebugEnv m; } request :: (DebugMonad m, Show resp, Typeable resp) => Request resp -> m resp requestBlock :: (DebugMonad m, Show resp, Typeable resp) => BlockCacheRequest resp -> m resp traceMsg :: DebugMonad m => String -> m () printRequestLog :: DebugMonad m => DebugEnv m -> IO () runDebug :: DebugMonad m => DebugEnv m -> m a -> IO a runDebugTrace :: DebugMonad m => DebugEnv m -> m a -> IO (a, [String]) newEnv :: DebugMonad m => Tracer IO String -> Mode -> IO (DebugEnv m) saveCache :: DebugMonad m => FilePath -> m () loadCache :: DebugMonad m => FilePath -> m () unsafeLiftIO :: DebugMonad m => IO a -> m a data Mode SnapshotMode :: FilePath -> Mode SocketMode :: Handle -> Mode module GHC.Debug.Client.RequestCache data RequestCache cacheReq :: Request resp -> resp -> RequestCache -> RequestCache lookupReq :: forall resp. Request resp -> RequestCache -> Maybe resp lookupBlocks :: RequestCache -> [RawBlock] emptyRequestCache :: RequestCache -- | Clear the part of the cache which will become invalid after pausing -- For example, we need to clear blocks, but can keep the info table -- caches. clearMovableRequests :: RequestCache -> RequestCache putCache :: RequestCache -> Put getCache :: Get RequestCache instance Data.Binary.Class.Binary GHC.Debug.Client.RequestCache.RequestCache -- | This module provides a simple implementation, which can be a lot -- faster if network latency is not an issue. module GHC.Debug.Client.Monad.Simple data Debuggee newtype DebugM a DebugM :: ReaderT Debuggee IO a -> DebugM a runSimple :: Debuggee -> DebugM a -> IO a instance Control.Monad.Fix.MonadFix GHC.Debug.Client.Monad.Simple.DebugM instance GHC.Base.Monad GHC.Debug.Client.Monad.Simple.DebugM instance GHC.Base.Applicative GHC.Debug.Client.Monad.Simple.DebugM instance GHC.Base.Functor GHC.Debug.Client.Monad.Simple.DebugM instance Control.Monad.Fail.MonadFail GHC.Debug.Client.Monad.Simple.DebugM instance GHC.Debug.Client.Monad.Class.DebugMonad GHC.Debug.Client.Monad.Simple.DebugM instance Data.Binary.Class.Binary GHC.Debug.Client.Monad.Simple.Snapshot module GHC.Debug.Client.Monad class (MonadFail m, Monad m) => DebugMonad m where { type DebugEnv m; } request :: (DebugMonad m, Show resp, Typeable resp) => Request resp -> m resp requestBlock :: (DebugMonad m, Show resp, Typeable resp) => BlockCacheRequest resp -> m resp traceMsg :: DebugMonad m => String -> m () printRequestLog :: DebugMonad m => DebugEnv m -> IO () runDebug :: DebugMonad m => DebugEnv m -> m a -> IO a runDebugTrace :: DebugMonad m => DebugEnv m -> m a -> IO (a, [String]) newEnv :: DebugMonad m => Tracer IO String -> Mode -> IO (DebugEnv m) saveCache :: DebugMonad m => FilePath -> m () loadCache :: DebugMonad m => FilePath -> m () unsafeLiftIO :: DebugMonad m => IO a -> m a -- | Run a DebugM a in the given environment. run :: Debuggee -> DebugM a -> IO a type DebugM = DebugM data Debuggee traceWrite :: DebugMonad m => Show a => a -> m () runTrace :: Debuggee -> DebugM a -> IO a -- | Bracketed version of debuggeeRun. Runs a debuggee, connects -- to it, runs the action, kills the process, then closes the debuggee. withDebuggeeRun :: FilePath -> FilePath -> (Debuggee -> IO a) -> IO a -- | Bracketed version of debuggeeConnect. Connects to a debuggee, -- runs the action, then closes the debuggee. withDebuggeeConnect :: FilePath -> (Debuggee -> IO a) -> IO a -- | Bracketed version of debuggeeConnectTCP. Connects to a -- debuggee, runs the action, then closes the debuggee. withDebuggeeConnectTCP :: String -> Word16 -> (Debuggee -> IO a) -> IO a -- | Run a debuggee and connect to it. Use debuggeeClose when -- you're done. debuggeeRun :: FilePath -> FilePath -> IO Debuggee debuggeeConnect :: FilePath -> IO Debuggee debuggeeConnectTCP :: String -> Word16 -> IO Debuggee -- | Connect to a debuggee on the given socket. Use debuggeeClose -- when you're done. debuggeeConnectWithTracer :: Tracer IO String -> FilePath -> IO Debuggee debuggeeConnectWithTracerTCP :: Tracer IO String -> String -> Word16 -> IO Debuggee -- | Close the connection to the debuggee. debuggeeClose :: Debuggee -> IO () -- | Create a debuggee by loading a snapshot created by snapshot. snapshotInit :: FilePath -> IO Debuggee snapshotInitWithTracer :: Tracer IO String -> FilePath -> IO Debuggee -- | Start an analysis session using a snapshot. This will not connect to a -- debuggee. The snapshot is created by snapshot. snapshotRun :: FilePath -> (Debuggee -> IO a) -> IO a outputRequestLog :: Debuggee -> IO () module GHC.Debug.Client.Query -- | Pause the debuggee pause :: Debuggee -> IO () fork :: Debuggee -> IO () pauseThen :: Debuggee -> DebugM b -> IO b -- | Resume the debuggee resume :: Debuggee -> IO () -- | Like pause, but wait for the debuggee to pause itself. It currently -- impossible to resume after a pause caused by a poll.?????????? Is that -- true???? can we not just call resume???? pausePoll :: Debuggee -> IO () -- | Bracketed version of pause/resume. withPause :: Debuggee -> IO a -> IO a -- | Fetch all the blocks from the debuggee and add them to the block cache precacheBlocks :: DebugM [RawBlock] -- | Query the debuggee for the list of GC Roots gcRoots :: DebugM [ClosurePtr] -- | Query the debuggee for all the blocks it knows about allBlocks :: DebugM [RawBlock] -- | Query the debuggee for source information about a specific info table. -- This requires your executable to be built with -- -finfo-table-map. getSourceInfo :: InfoTablePtr -> DebugM (Maybe SourceInformation) -- | Query the debuggee for the list of saved objects. savedObjects :: DebugM [ClosurePtr] requestCCSMain :: DebugM CCSPtr -- | Query the debuggee for the protocol version version :: DebugM Version dereferenceClosures :: [ClosurePtr] -> DebugM [SizedClosure] -- | Consult the BlockCache for the block which contains a specific -- closure, if it's not there then try to fetch the right block, if that -- fails, call dereferenceClosureDirect dereferenceClosure :: ClosurePtr -> DebugM SizedClosure -- | Decode a closure corresponding to the given ClosurePtr You -- should not use this function directly unless you know what you are -- doing. dereferenceClosure will be much faster in general. dereferenceClosureDirect :: ClosurePtr -> DebugM SizedClosure dereferenceClosureC :: ClosurePtr -> DebugM SizedClosureC dereferenceToClosurePtr :: SizedClosure -> DebugM SizedClosureP addConstrDesc :: SizedClosure -> DebugM SizedClosureC -- | Deference some StackFrames from a given StackCont dereferenceStack :: StackCont -> DebugM StackFrames -- | Derference the PapPayload from the PayloadCont dereferencePapPayload :: PayloadCont -> DebugM PapPayload dereferenceConDesc :: ConstrDescCont -> DebugM ConstrDesc dereferenceInfoTable :: InfoTablePtr -> DebugM StgInfoTable dereferenceSRT :: InfoTablePtr -> DebugM SrtPayload dereferenceCCS :: CCSPtr -> DebugM CCSPayload dereferenceCCSDirect :: CCSPtr -> DebugM CCSPayload dereferenceCC :: CCPtr -> DebugM CCPayload dereferenceIndexTable :: IndexTablePtr -> DebugM IndexTable dereferenceIndexTableDirect :: IndexTablePtr -> DebugM IndexTable -- | 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 "") g) --module GHC.Debug.Client data Debuggee type DebugM = DebugM -- | Run a debuggee and connect to it. Use debuggeeClose when -- you're done. debuggeeRun :: FilePath -> FilePath -> IO Debuggee debuggeeConnect :: FilePath -> IO Debuggee -- | Close the connection to the debuggee. debuggeeClose :: Debuggee -> IO () -- | Bracketed version of debuggeeRun. Runs a debuggee, connects -- to it, runs the action, kills the process, then closes the debuggee. withDebuggeeRun :: FilePath -> FilePath -> (Debuggee -> IO a) -> IO a -- | Bracketed version of debuggeeConnect. Connects to a debuggee, -- runs the action, then closes the debuggee. withDebuggeeConnect :: FilePath -> (Debuggee -> IO a) -> IO a socketDirectory :: IO FilePath -- | Start an analysis session using a snapshot. This will not connect to a -- debuggee. The snapshot is created by snapshot. snapshotRun :: FilePath -> (Debuggee -> IO a) -> IO a -- | Run a DebugM a in the given environment. run :: Debuggee -> DebugM a -> IO a runTrace :: Debuggee -> DebugM a -> IO a -- | 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 -- | Pause the debuggee pause :: Debuggee -> IO () fork :: Debuggee -> IO () pauseThen :: Debuggee -> DebugM b -> IO b -- | Resume the debuggee resume :: Debuggee -> IO () -- | Like pause, but wait for the debuggee to pause itself. It currently -- impossible to resume after a pause caused by a poll.?????????? Is that -- true???? can we not just call resume???? pausePoll :: Debuggee -> IO () -- | Bracketed version of pause/resume. withPause :: Debuggee -> IO a -> IO a -- | Query the debuggee for the protocol version version :: DebugM Version -- | Query the debuggee for the list of GC Roots gcRoots :: DebugM [ClosurePtr] -- | Query the debuggee for all the blocks it knows about allBlocks :: DebugM [RawBlock] -- | Query the debuggee for source information about a specific info table. -- This requires your executable to be built with -- -finfo-table-map. getSourceInfo :: InfoTablePtr -> DebugM (Maybe SourceInformation) -- | Query the debuggee for the list of saved objects. savedObjects :: DebugM [ClosurePtr] -- | Fetch all the blocks from the debuggee and add them to the block cache precacheBlocks :: DebugM [RawBlock] -- | Consult the BlockCache for the block which contains a specific -- closure, if it's not there then try to fetch the right block, if that -- fails, call dereferenceClosureDirect dereferenceClosure :: ClosurePtr -> DebugM SizedClosure dereferenceToClosurePtr :: SizedClosure -> DebugM SizedClosureP addConstrDesc :: SizedClosure -> DebugM SizedClosureC requestCCSMain :: DebugM CCSPtr dereferenceClosures :: [ClosurePtr] -> DebugM [SizedClosure] -- | Deference some StackFrames from a given StackCont dereferenceStack :: StackCont -> DebugM StackFrames -- | Derference the PapPayload from the PayloadCont dereferencePapPayload :: PayloadCont -> DebugM PapPayload dereferenceConDesc :: ConstrDescCont -> DebugM ConstrDesc dereferenceInfoTable :: InfoTablePtr -> DebugM StgInfoTable dereferenceIndexTable :: IndexTablePtr -> DebugM IndexTable dereferenceSRT :: InfoTablePtr -> DebugM SrtPayload dereferenceCCS :: CCSPtr -> DebugM CCSPayload dereferenceCC :: CCPtr -> DebugM CCPayload class () => Hextraversable (m :: Type -> Type -> Type -> Type -> Type -> Type -> Type) hextraverse :: (Hextraversable m, Applicative f) => (a -> f b) -> (c -> f d) -> (e -> f g) -> (h -> f i) -> (j -> f k) -> (l -> f n) -> m a c e h j l -> f (m b d g i k n) -- | 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 (HeapGraph Size) -- | 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 (HeapGraph Size) -- | The whole graph. The suggested interface is to only use -- lookupHeapGraph, as the internal representation may change. -- Nevertheless, we export it here: Sometimes the user knows better what -- he needs than we do. data () => HeapGraph a HeapGraph :: !NonEmpty ClosurePtr -> !IntMap (HeapGraphEntry a) -> HeapGraph a [roots] :: HeapGraph a -> !NonEmpty ClosurePtr [graph] :: HeapGraph a -> !IntMap (HeapGraphEntry a) -- | For heap graphs, i.e. data structures that also represent sharing and -- cyclic structures, these are the entries. If the referenced value is -- Nothing, then we do not have that value in the map, most -- likely due to exceeding the recursion bound passed to -- buildHeapGraph. -- -- Besides a pointer to the stored value and the closure representation -- we have a slot for arbitrary data, for the user's convenience. data () => HeapGraphEntry a HeapGraphEntry :: ClosurePtr -> DebugClosure CCSPtr SrtHI PapHI ConstrDesc StackHI (Maybe HeapGraphIndex) -> a -> HeapGraphEntry a [hgeClosurePtr] :: HeapGraphEntry a -> ClosurePtr [hgeClosure] :: HeapGraphEntry a -> DebugClosure CCSPtr SrtHI PapHI ConstrDesc StackHI (Maybe HeapGraphIndex) [hgeData] :: HeapGraphEntry a -> a -- | Pretty-prints a HeapGraph. The resulting string contains newlines. -- Example for let s = "Ki" in (s, s, cycle "Ho"): -- --
-- let x1 = "Ki" -- x6 = C# 'H' : C# 'o' : x6 -- in (x1,x1,x6) --ppHeapGraph :: (a -> String) -> HeapGraph a -> String traceWrite :: DebugMonad m => Show a => a -> m () traceMsg :: DebugMonad m => String -> m () saveCache :: DebugMonad m => FilePath -> m () loadCache :: DebugMonad m => FilePath -> m () data () => SourceInformation SourceInformation :: !String -> !ClosureType -> !String -> !String -> !String -> !String -> SourceInformation [infoName] :: SourceInformation -> !String [infoClosureType] :: SourceInformation -> !ClosureType [infoType] :: SourceInformation -> !String [infoLabel] :: SourceInformation -> !String [infoModule] :: SourceInformation -> !String [infoPosition] :: SourceInformation -> !String data () => RawBlock RawBlock :: BlockPtr -> Word16 -> ByteString -> RawBlock data () => BlockPtr data () => StackPtr data () => ClosurePtr data () => InfoTablePtr data () => CCPtr data () => CCSPtr data () => IndexTablePtr type StackHI = GenStackFrames GenSrtPayload Maybe HeapGraphIndex Maybe HeapGraphIndex type PapHI = GenPapPayload Maybe HeapGraphIndex type HeapGraphIndex = ClosurePtr module GHC.Debug.Client.Search findClosures :: (HeapGraphEntry a -> Bool) -> HeapGraph a -> [HeapGraphEntry a] findConstructors :: String -> HeapGraph a -> [HeapGraphEntry a] findWithInfoTable :: InfoTablePtr -> HeapGraph a -> [HeapGraphEntry a] -- | The whole graph. The suggested interface is to only use -- lookupHeapGraph, as the internal representation may change. -- Nevertheless, we export it here: Sometimes the user knows better what -- he needs than we do. data () => HeapGraph a HeapGraph :: !NonEmpty ClosurePtr -> !IntMap (HeapGraphEntry a) -> HeapGraph a [roots] :: HeapGraph a -> !NonEmpty ClosurePtr [graph] :: HeapGraph a -> !IntMap (HeapGraphEntry a) -- | For heap graphs, i.e. data structures that also represent sharing and -- cyclic structures, these are the entries. If the referenced value is -- Nothing, then we do not have that value in the map, most -- likely due to exceeding the recursion bound passed to -- buildHeapGraph. -- -- Besides a pointer to the stored value and the closure representation -- we have a slot for arbitrary data, for the user's convenience. data () => HeapGraphEntry a HeapGraphEntry :: ClosurePtr -> DebugClosure CCSPtr SrtHI PapHI ConstrDesc StackHI (Maybe HeapGraphIndex) -> a -> HeapGraphEntry a [hgeClosurePtr] :: HeapGraphEntry a -> ClosurePtr [hgeClosure] :: HeapGraphEntry a -> DebugClosure CCSPtr SrtHI PapHI ConstrDesc StackHI (Maybe HeapGraphIndex) [hgeData] :: HeapGraphEntry a -> a module GHC.Debug.CostCentres -- | Find all cost centre stack parts that are transitively children of the -- cost centre with the given id. findAllChildrenOfCC :: (CCPayload -> Bool) -> DebugM (Set CCSPtr) -- | Find all Cost Centre Stacks that reference precisely the cost centre -- with the given id. findExactlyByCC :: (CCPayload -> Bool) -> DebugM (Set CCSPtr) findAllCCSPayloads :: DebugM CCSSet traverseCCSPayloads :: DebugM () -- | Flatten an optional index table pointer into a list of CCS Payloads. flattenIndexTable :: Maybe IndexTablePtr -> DebugM [CCSPayload] traverseIndexTable :: Maybe IndexTablePtr -> (CCPtr -> CCSPtr -> Bool -> DebugM a) -> DebugM [a] foldIndexTable :: (CCPtr -> CCSPtr -> Bool -> a -> DebugM a) -> a -> Maybe IndexTablePtr -> DebugM a newtype CCSSet CCSSet :: IntSet -> CCSSet memberCCSSet :: CCSPtr -> CCSSet -> Bool module GHC.Debug.Dominators computeDominators :: HeapGraph a -> [Tree (HeapGraphEntry a)] retainerSize :: HeapGraph Size -> [Tree (HeapGraphEntry (Size, RetainerSize))] convertToHeapGraph :: Tree (HeapGraphEntry a) -> IntMap (HeapGraphEntry a) annotateWithRetainerSize :: HeapGraph Size -> HeapGraph (Size, RetainerSize) -- | Functions to support the constant space traversal of a heap. This -- module is like the Trace module but performs the tracing in parellel. -- The speed-up is quite modest but hopefully can be improved in future. -- -- The tracing functions create a thread for each MBlock which we -- traverse, closures are then sent to the relevant threads to be -- dereferenced and thread-local storage is accumulated. module GHC.Debug.ParTrace -- | A generic heap traversal function which will use a small amount of -- memory linear in the heap size. Using this function with appropriate -- accumulation functions you should be able to traverse quite big heaps -- in not a huge amount of memory. -- -- The performance of this parallel version depends on how much -- contention the functions given in TraceFunctionsIO content for -- the handle connecting for the debuggee (which is protected by an -- MVar). With no contention, and precached blocks, the workload -- can be very evenly distributed leading to high core utilisation. -- -- As performance depends highly on contention, snapshot mode is much -- more amenable to parallelisation where the time taken for requests is -- much lower. traceParFromM :: Monoid s => TraceFunctionsIO a s -> [ClosurePtrWithInfo a] -> DebugM s -- | A parallel tracing function. tracePar :: [ClosurePtr] -> DebugM () data TraceFunctionsIO a s TraceFunctionsIO :: !GenPapPayload ClosurePtr -> DebugM () -> !GenSrtPayload ClosurePtr -> DebugM () -> !GenStackFrames SrtCont ClosurePtr -> DebugM () -> !ClosurePtr -> SizedClosure -> a -> DebugM (a, s, DebugM () -> DebugM ()) -> !ClosurePtr -> a -> DebugM s -> !CCSPtr -> DebugM s -> !ConstrDesc -> DebugM () -> !CCSPtr -> CCSPayload -> DebugM s -> TraceFunctionsIO a s [papTrace] :: TraceFunctionsIO a s -> !GenPapPayload ClosurePtr -> DebugM () [srtTrace] :: TraceFunctionsIO a s -> !GenSrtPayload ClosurePtr -> DebugM () [stackTrace] :: TraceFunctionsIO a s -> !GenStackFrames SrtCont ClosurePtr -> DebugM () [closTrace] :: TraceFunctionsIO a s -> !ClosurePtr -> SizedClosure -> a -> DebugM (a, s, DebugM () -> DebugM ()) [visitedClosVal] :: TraceFunctionsIO a s -> !ClosurePtr -> a -> DebugM s [visitedCcsVal] :: TraceFunctionsIO a s -> !CCSPtr -> DebugM s [conDescTrace] :: TraceFunctionsIO a s -> !ConstrDesc -> DebugM () [ccsTrace] :: TraceFunctionsIO a s -> !CCSPtr -> CCSPayload -> DebugM s -- | A ClosurePtr with some additional information which needs to be -- communicated across to another thread. data ClosurePtrWithInfo a ClosurePtrWithInfo :: !a -> !ClosurePtr -> ClosurePtrWithInfo a CCSPtrWithInfo :: CCSPtr -> ClosurePtrWithInfo a module GHC.Debug.Profile.Types newtype Count Count :: Int -> Count [getCount] :: Count -> Int newtype Sample Sample :: [ClosurePtr] -> Sample [getSamples] :: Sample -> [ClosurePtr] data CensusStats CS :: !Count -> !Size -> !Max Size -> !Sample -> CensusStats [cscount] :: CensusStats -> !Count [cssize] :: CensusStats -> !Size [csmax] :: CensusStats -> !Max Size [sample] :: CensusStats -> !Sample mkCS :: ClosurePtr -> Size -> CensusStats instance GHC.Classes.Eq GHC.Debug.Profile.Types.Count instance GHC.Classes.Ord GHC.Debug.Profile.Types.Count instance GHC.Show.Show GHC.Debug.Profile.Types.Count instance GHC.Num.Num GHC.Debug.Profile.Types.Count instance GHC.Base.Monoid GHC.Debug.Profile.Types.Count instance GHC.Base.Semigroup GHC.Debug.Profile.Types.Count instance GHC.Classes.Eq GHC.Debug.Profile.Types.Sample instance GHC.Show.Show GHC.Debug.Profile.Types.Sample instance GHC.Classes.Eq GHC.Debug.Profile.Types.CensusStats instance GHC.Show.Show GHC.Debug.Profile.Types.CensusStats instance GHC.Base.Monoid GHC.Debug.Profile.Types.CensusStats instance GHC.Base.Semigroup GHC.Debug.Profile.Types.CensusStats instance GHC.Base.Monoid GHC.Debug.Profile.Types.Sample instance GHC.Base.Semigroup GHC.Debug.Profile.Types.Sample -- | Functions to support the constant space traversal of a heap. module GHC.Debug.Trace -- | A generic heap traversal function which will use a small amount of -- memory linear in the heap size. Using this function with appropiate -- accumulation functions you should be able to traverse quite big heaps -- in not a huge amount of memory. traceFromM :: C m => TraceFunctions m -> [ClosurePtr] -> m DebugM () data TraceFunctions m TraceFunctions :: !GenPapPayload ClosurePtr -> m DebugM () -> !GenSrtPayload ClosurePtr -> m DebugM () -> !GenStackFrames SrtCont ClosurePtr -> m DebugM () -> !ClosurePtr -> SizedClosure -> m DebugM () -> m DebugM () -> !ClosurePtr -> m DebugM () -> !ConstrDesc -> m DebugM () -> !CCSPtr -> CCSPayload -> m DebugM () -> TraceFunctions m [papTrace] :: TraceFunctions m -> !GenPapPayload ClosurePtr -> m DebugM () [srtTrace] :: TraceFunctions m -> !GenSrtPayload ClosurePtr -> m DebugM () [stackTrace] :: TraceFunctions m -> !GenStackFrames SrtCont ClosurePtr -> m DebugM () [closTrace] :: TraceFunctions m -> !ClosurePtr -> SizedClosure -> m DebugM () -> m DebugM () [visitedVal] :: TraceFunctions m -> !ClosurePtr -> m DebugM () [conDescTrace] :: TraceFunctions m -> !ConstrDesc -> m DebugM () [ccsTrace] :: TraceFunctions m -> !CCSPtr -> CCSPayload -> m DebugM () justClosures :: C m => (ClosurePtr -> SizedClosure -> m DebugM () -> m DebugM ()) -> TraceFunctions m module GHC.Debug.Thunks thunkAnalysis :: [ClosurePtr] -> DebugM (Map (Maybe SourceInformation) Count) module GHC.Debug.Strings -- | Find all the strings and then print out how many duplicates there are stringProgram :: Debuggee -> IO () arrWordsProgram :: Debuggee -> IO () -- | Find how many distinct ArrWords there are arrWordsAnalysis :: [ClosurePtr] -> DebugM (Map ByteString (Set ClosurePtr)) -- | Find the parents of Bin nodes stringAnalysis :: [ClosurePtr] -> DebugM (Map String (Set ClosurePtr)) decodeString :: ClosurePtr -> DebugM String -- | Functions for creating and running snapshots. module GHC.Debug.Snapshot -- | Make a snapshot of the current heap and save it to the given file. snapshot :: FilePath -> DebugM () -- | Pause the process and create a snapshot of the heap. The snapshot can -- then be loaded with snapshotRun in order to perform offline -- analysis. makeSnapshot :: Debuggee -> FilePath -> IO () -- | Start an analysis session using a snapshot. This will not connect to a -- debuggee. The snapshot is created by snapshot. snapshotRun :: FilePath -> (Debuggee -> IO a) -> IO a -- | Traverse the tree from GC roots, to populate the caches with -- everything necessary. traceFrom :: [ClosurePtr] -> DebugM () -- | Functions for computing retainers module GHC.Debug.Retainers -- | From the given roots, find any path to one of the given pointers. -- Note: This function can be quite slow! The first argument is a limit -- to how many paths to find. You should normally set this to a small -- number such as 10. findRetainers :: Maybe Int -> ClosureFilter -> [ClosurePtr] -> DebugM [[ClosurePtr]] findRetainersOf :: Maybe Int -> [ClosurePtr] -> [ClosurePtr] -> DebugM [[ClosurePtr]] findRetainersOfConstructor :: Maybe Int -> [ClosurePtr] -> String -> DebugM [[ClosurePtr]] findRetainersOfConstructorExact :: Maybe Int -> [ClosurePtr] -> String -> DebugM [[ClosurePtr]] findRetainersOfInfoTable :: Maybe Int -> [ClosurePtr] -> InfoTablePtr -> DebugM [[ClosurePtr]] addLocationToStack :: [ClosurePtr] -> DebugM [(SizedClosureP, Maybe SourceInformation)] displayRetainerStack :: [(String, [(SizedClosureP, Maybe SourceInformation)])] -> IO () addLocationToStack' :: [ClosurePtr] -> DebugM [(ClosurePtr, SizedClosureP, Maybe SourceInformation)] displayRetainerStack' :: [(String, [(ClosurePtr, SizedClosureP, Maybe SourceInformation)])] -> IO () findRetainersOfArrWords :: Maybe Int -> [ClosurePtr] -> Size -> DebugM [[ClosurePtr]] data EraRange EraRange :: Word64 -> Word64 -> EraRange [startEra] :: EraRange -> Word64 [endEra] :: EraRange -> Word64 profHeaderInEraRange :: Maybe (ProfHeader a) -> Maybe EraRange -> Bool data ClosureFilter ConstructorDescFilter :: (ConstrDesc -> Bool) -> ClosureFilter InfoFilter :: (StgInfoTable -> Bool) -> ClosureFilter InfoPtrFilter :: (InfoTablePtr -> Bool) -> ClosureFilter InfoSourceFilter :: (SourceInformation -> Bool) -> ClosureFilter SizeFilter :: (Size -> Bool) -> ClosureFilter ProfHeaderFilter :: (Maybe ProfHeaderWithPtr -> Bool) -> ClosureFilter AddressFilter :: (ClosurePtr -> Bool) -> ClosureFilter AndFilter :: ClosureFilter -> ClosureFilter -> ClosureFilter OrFilter :: ClosureFilter -> ClosureFilter -> ClosureFilter NotFilter :: ClosureFilter -> ClosureFilter PureFilter :: Bool -> ClosureFilter profHeaderReferencesCCS :: Maybe ProfHeaderWithPtr -> Set CCSPtr -> Bool findRetainersOfEra :: Maybe Int -> EraRange -> [ClosurePtr] -> DebugM [[ClosurePtr]] instance GHC.Show.Show GHC.Debug.Retainers.EraRange instance GHC.Classes.Ord GHC.Debug.Retainers.EraRange instance GHC.Classes.Eq GHC.Debug.Retainers.EraRange -- | Functions for performing whole heap census in the style of the normal -- - heap profiling module GHC.Debug.Profile -- | Perform a heap census in the same style as the -hT profile. censusClosureType :: [ClosurePtr] -> DebugM CensusByClosureType -- | Perform a 2-level census where the keys are the type of the closure in -- addition to the type of ptrs of the closure. This can be used to -- distinguish between lists of different type for example. census2LevelClosureType :: [ClosurePtr] -> DebugM CensusByClosureType -- | General function for performing a heap census in constant memory closureCensusBy :: forall k v. (Semigroup v, Ord k) => (ClosurePtr -> SizedClosure -> DebugM (Maybe (k, v))) -> [ClosurePtr] -> DebugM (Map k v) type CensusByClosureType = Map (ProfileKey, ProfileKeyArgs) CensusStats writeCensusByClosureType :: FilePath -> CensusByClosureType -> IO () data CensusStats CS :: !Count -> !Size -> !Max Size -> !Sample -> CensusStats [cscount] :: CensusStats -> !Count [cssize] :: CensusStats -> !Size [csmax] :: CensusStats -> !Max Size [sample] :: CensusStats -> !Sample data ProfileKey ProfileConstrDesc :: !ConstrDescText -> ProfileKey ProfileClosureDesc :: !Text -> ProfileKey data ProfileKeyArgs ArrKeyArgs :: !ProfileKey -> !Int -> ProfileKeyArgs AllKeyArgs :: !Vector ProfileKey -> ProfileKeyArgs NoArgs :: ProfileKeyArgs -- | Show the full ProfileKey, including package and module -- locations if available. prettyProfileKey :: ProfileKey -> Text -- | Show the ProfileKey in a shortened form if possible. For -- example, it omits package and module locations for -- ProfileConstrDesc. prettyShortProfileKey :: ProfileKey -> Text prettyProfileKeyArgs :: ProfileKeyArgs -> Text prettyProfileKeyArgs' :: (ProfileKey -> Text) -> ProfileKeyArgs -> Text prettyShortProfileKeyArgs :: ProfileKeyArgs -> Text mkCS :: ClosurePtr -> Size -> CensusStats newtype Count Count :: Int -> Count [getCount] :: Count -> Int closureToKey :: DebugClosure ccs srt a ConstrDesc c d -> Text -- | ConstrDescText wraps a ConstrDesc but is backed by a -- Text. -- -- More efficient to keep around than ConstrDesc. data ConstrDescText packConstrDesc :: ConstrDesc -> ConstrDescText pkgsText :: ConstrDescText -> Text modlText :: ConstrDescText -> Text nameText :: ConstrDescText -> Text instance GHC.Classes.Eq GHC.Debug.Profile.ConstrDescText instance GHC.Classes.Ord GHC.Debug.Profile.ConstrDescText instance GHC.Show.Show GHC.Debug.Profile.ConstrDescText instance GHC.Classes.Eq GHC.Debug.Profile.ProfileKey instance GHC.Classes.Ord GHC.Debug.Profile.ProfileKey instance GHC.Show.Show GHC.Debug.Profile.ProfileKey instance GHC.Classes.Eq GHC.Debug.Profile.ProfileKeyArgs instance GHC.Classes.Ord GHC.Debug.Profile.ProfileKeyArgs instance GHC.Show.Show GHC.Debug.Profile.ProfileKeyArgs -- | Functions for analysing memory fragmentation module GHC.Debug.Fragmentation -- | Print a summary of the given raw blocks This is useful to see how many -- MBlocks and how many pinned blocks there are. summariseBlocks :: [RawBlock] -> IO () -- | Perform a heap census by which MBlock each closure lives in censusByMBlock :: [ClosurePtr] -> DebugM (Map BlockPtr CensusStats) printMBlockCensus :: Map BlockPtr CensusStats -> IO () -- | Perform a census based on which block each closure resides in. censusByBlock :: [ClosurePtr] -> DebugM (Map BlockPtr CensusStats) -- | Print out a block census printBlockCensus :: Map BlockPtr CensusStats -> IO () -- | Only census the given (pinned) blocks censusPinnedBlocks :: [RawBlock] -> [ClosurePtr] -> DebugM (Map BlockPtr PinnedCensusStats) newtype PinnedCensusStats PinnedCensusStats :: (CensusStats, [(ClosurePtr, SizedClosure)]) -> PinnedCensusStats -- | Given a pinned block census, find the ARR_WORDS objects which are in -- the blocks which are < 10 % utilised. The return list is sorted by -- how many times each distinct ARR_WORDS appears on the heap. findBadPtrs :: Map k PinnedCensusStats -> [((Count, [ClosurePtr]), String)] -- | Print either a MBlock or Block census as a histogram histogram :: Word64 -> [CensusStats] -> IO () instance GHC.Base.Semigroup GHC.Debug.Fragmentation.PinnedCensusStats -- | Attempt to find duplicate objects on the heap. The analysis is not -- exact but attempts to find closures which are identical, and could be -- shared. module GHC.Debug.ObjectEquiv objectEquiv :: Debuggee -> IO () objectEquivAnalysis :: DebugM (EquivMap, HeapGraph Size) printObjectEquiv :: EquivMap -> IO () type EquivMap = OrdPSQ PtrClosure Int ClosurePtr module GHC.Debug.Count parCount :: [ClosurePtr] -> DebugM CensusStats -- | Simple statistics about a heap, total objects, size and maximum object -- size count :: [ClosurePtr] -> DebugM CensusStats -- | Type Points From analysis in the style of - Cork: Dynamic Memory Leak -- Detectionfor Garbage-Collected Languages - -- https://dl.acm.org/doi/10.1145/1190216.1190224 - module GHC.Debug.TypePointsFrom -- | Perform a "type points from" heap census typePointsFrom :: [ClosurePtr] -> DebugM TypePointsFrom -- | Repeatedly call typesPointsFrom and perform the leak -- detection analysis. detectLeaks :: Int -> Debuggee -> IO () data TypePointsFrom TypePointsFrom :: !MonoidalMap Key CensusStats -> !MonoidalMap Edge CensusStats -> TypePointsFrom [nodes] :: TypePointsFrom -> !MonoidalMap Key CensusStats [edges] :: TypePointsFrom -> !MonoidalMap Edge CensusStats getNodes :: TypePointsFrom -> Map Key CensusStats getEdges :: TypePointsFrom -> Map Edge CensusStats edgeSource :: Edge -> Key edgeTarget :: Edge -> Key type Key = InfoTablePtr data Edge Edge :: !Key -> !Key -> Edge getKey :: InfoTablePtr -> DebugM String instance GHC.Show.Show GHC.Debug.TypePointsFrom.Edge instance GHC.Classes.Ord GHC.Debug.TypePointsFrom.Edge instance GHC.Classes.Eq GHC.Debug.TypePointsFrom.Edge instance GHC.Show.Show GHC.Debug.TypePointsFrom.TypePointsFrom instance GHC.Show.Show GHC.Debug.TypePointsFrom.RankInfo instance GHC.Base.Monoid GHC.Debug.TypePointsFrom.TypePointsFrom instance GHC.Base.Semigroup GHC.Debug.TypePointsFrom.TypePointsFrom module GHC.Debug.GML writeTpfToGML :: FilePath -> TypePointsFrom -> SourceInfoMap -> IO () -- | Exports TypePointsFrom graph to a GML file addSourceInfo :: TypePointsFrom -> DebugM SourceInfoMap typePointsFromToGML :: FilePath -> Debuggee -> IO ()