-- 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.3.0.0 module GHC.Debug.Client.BlockCache data BlockCache data BlockCacheRequest a [LookupClosure] :: ClosurePtr -> BlockCacheRequest RawClosure [PopulateBlockCache] :: BlockCacheRequest [RawBlock] handleBlockReq :: (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 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 -- | Run a debuggee and connect to it. Use debuggeeClose when -- you're done. debuggeeRun :: FilePath -> FilePath -> IO Debuggee debuggeeConnect :: FilePath -> IO Debuggee -- | Connect to a debuggee on the given socket. Use debuggeeClose -- when you're done. debuggeeConnectWithTracer :: Tracer IO String -> FilePath -> 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] -- | 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 -- | 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 -- | 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 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 class Quadtraversable (m :: TYPE LiftedRep -> TYPE LiftedRep -> TYPE LiftedRep -> TYPE LiftedRep -> TYPE LiftedRep) quadtraverse :: (Quadtraversable m, Applicative f) => (a -> f b) -> (c -> f d) -> (e -> f g) -> (h -> f i) -> m a c e h -> f (m b d g i) -- | 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) data HeapGraph a HeapGraph :: !NonEmpty ClosurePtr -> !IntMap (HeapGraphEntry a) -> HeapGraph a [roots] :: HeapGraph a -> !NonEmpty ClosurePtr [graph] :: HeapGraph a -> !IntMap (HeapGraphEntry a) data HeapGraphEntry a HeapGraphEntry :: ClosurePtr -> DebugClosure PapHI ConstrDesc StackHI (Maybe HeapGraphIndex) -> a -> HeapGraphEntry a [hgeClosurePtr] :: HeapGraphEntry a -> ClosurePtr [hgeClosure] :: HeapGraphEntry a -> DebugClosure PapHI ConstrDesc StackHI (Maybe HeapGraphIndex) [hgeData] :: HeapGraphEntry a -> a 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 type StackHI = GenStackFrames 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] data HeapGraph a HeapGraph :: !NonEmpty ClosurePtr -> !IntMap (HeapGraphEntry a) -> HeapGraph a [roots] :: HeapGraph a -> !NonEmpty ClosurePtr [graph] :: HeapGraph a -> !IntMap (HeapGraphEntry a) data HeapGraphEntry a HeapGraphEntry :: ClosurePtr -> DebugClosure PapHI ConstrDesc StackHI (Maybe HeapGraphIndex) -> a -> HeapGraphEntry a [hgeClosurePtr] :: HeapGraphEntry a -> ClosurePtr [hgeClosure] :: HeapGraphEntry a -> DebugClosure PapHI ConstrDesc StackHI (Maybe HeapGraphIndex) [hgeData] :: HeapGraphEntry a -> a 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 appropiate -- accumulation functions you should be able to traverse quite big heaps -- in not a huge amount of memory. -- -- The performance of this parralel 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 parrelisation where the time taken for requests is -- much lower. traceParFromM :: Monoid s => TraceFunctionsIO a s -> [ClosurePtrWithInfo a] -> DebugM s -- | A parellel tracing function. tracePar :: [ClosurePtr] -> DebugM () data TraceFunctionsIO a s TraceFunctionsIO :: !GenPapPayload ClosurePtr -> DebugM () -> !GenStackFrames ClosurePtr -> DebugM () -> !ClosurePtr -> SizedClosure -> a -> DebugM (a, s, DebugM () -> DebugM ()) -> !ClosurePtr -> a -> DebugM s -> !ConstrDesc -> DebugM () -> TraceFunctionsIO a s [papTrace] :: TraceFunctionsIO a s -> !GenPapPayload ClosurePtr -> DebugM () [stackTrace] :: TraceFunctionsIO a s -> !GenStackFrames ClosurePtr -> DebugM () [closTrace] :: TraceFunctionsIO a s -> !ClosurePtr -> SizedClosure -> a -> DebugM (a, s, DebugM () -> DebugM ()) [visitedVal] :: TraceFunctionsIO a s -> !ClosurePtr -> a -> DebugM s [conDescTrace] :: TraceFunctionsIO a s -> !ConstrDesc -> DebugM () -- | A ClosurePtr with some additional information which needs to be -- communicated across to another thread. data ClosurePtrWithInfo a ClosurePtrWithInfo :: !a -> !ClosurePtr -> ClosurePtrWithInfo a module GHC.Debug.Profile.Types newtype Count Count :: Int -> Count data CensusStats CS :: !Count -> !Size -> !Max Size -> CensusStats [cscount] :: CensusStats -> !Count [cssize] :: CensusStats -> !Size [csmax] :: CensusStats -> !Max Size mkCS :: 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.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 -- | 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 () -> !GenStackFrames ClosurePtr -> m DebugM () -> !ClosurePtr -> SizedClosure -> m DebugM () -> m DebugM () -> !ClosurePtr -> m DebugM () -> !ConstrDesc -> m DebugM () -> TraceFunctions m [papTrace] :: TraceFunctions m -> !GenPapPayload ClosurePtr -> m DebugM () [stackTrace] :: TraceFunctions m -> !GenStackFrames ClosurePtr -> m DebugM () [closTrace] :: TraceFunctions m -> !ClosurePtr -> SizedClosure -> m DebugM () -> m DebugM () [visitedVal] :: TraceFunctions m -> !ClosurePtr -> m DebugM () [conDescTrace] :: TraceFunctions m -> !ConstrDesc -> m DebugM () 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)) -- | 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 findRetainersOf :: Maybe Int -> [ClosurePtr] -> [ClosurePtr] -> DebugM [[ClosurePtr]] findRetainersOfConstructor :: Maybe Int -> [ClosurePtr] -> String -> DebugM [[ClosurePtr]] findRetainersOfConstructorExact :: Maybe Int -> [ClosurePtr] -> String -> DebugM [[ClosurePtr]] -- | 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 -> [ClosurePtr] -> (ClosurePtr -> SizedClosure -> DebugM Bool) -> DebugM [[ClosurePtr]] addLocationToStack :: [ClosurePtr] -> DebugM [(SizedClosureC, Maybe SourceInformation)] displayRetainerStack :: [(String, [(SizedClosureC, Maybe SourceInformation)])] -> IO () addLocationToStack' :: [ClosurePtr] -> DebugM [(ClosurePtr, SizedClosureC, Maybe SourceInformation)] displayRetainerStack' :: [(String, [(ClosurePtr, SizedClosureC, Maybe SourceInformation)])] -> IO () -- | Functions for performing whole heap census in the style of the normal -- - heap profiling module GHC.Debug.Profile -- | Peform a profile at the given interval (in seconds), the result will -- be rendered after each iteration using eventlog2html. profile :: FilePath -> Int -> Debuggee -> IO () -- | 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 Text CensusStats writeCensusByClosureType :: FilePath -> CensusByClosureType -> IO () data CensusStats CS :: !Count -> !Size -> !Max Size -> CensusStats [cscount] :: CensusStats -> !Count [cssize] :: CensusStats -> !Size [csmax] :: CensusStats -> !Max Size mkCS :: Size -> CensusStats newtype Count Count :: Int -> Count closureToKey :: DebugClosure a ConstrDesc c d -> Text -- | 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 ()