nomeata / ghc-heap-view

Extract the heap representation of Haskell values and thunks
BSD 3-Clause "New" or "Revised" License
50 stars 19 forks source link

Fixing the Disassembler #37

Open Tarmean opened 2 years ago

Tarmean commented 2 years ago

I believe I figured out why the disassembler started acting up. Since this commit the BRK_FUN op has an extra argument. This creates an off-by-one error in the disassembler for operands after the breakpoint.

With profiling enabled (e.g. -fexternal-interpreter -prof) the extra argument is a valid offset to the literal array which contains a pointer to the cost centre . This means we could retrieve sourcelocation and name for many bytecode objects. This makes the heap much less opaque so I'd like to expose the cost centre .

If the disassembler is still supported I can open a pull request. I'm not entirely sure how the plumbing should work, the disassembler is currently pure but the CC is immutable and doesn't move. Using lazy IO to dereference it or returning an opaque newtype with an IO function to dereference it both work.

Here is a sketch of the changes if others want to play around with this:

            bci_BRK_FUN -> do
                _ <- getWord16host
                _ <- getWord16host
                _ <- getWord16host
+#if defined(PROFILING)
+                ccsBox <- Just . fromIntegral <$> getLiteral
+#else
+                _ <- getWord16host
+                let ccsBox = Nothing
+#endif
-                 return BCIBRK_FUN
+                return (BCIBRK_FUN ccsBox)

The costcentre can be used to get a source location and name out of many BCO's like:

hellaUnsafePtr :: Int -> Ptr CCS.CostCentre
hellaUnsafePtr (I# i#) = Ptr (unsafeCoerce# i#)
showCostCentre :: Ptr CCS.CostCentre -> IO String
showCostCentre cc = do
  label <- GHC.peekCString utf8 =<< ccLabel cc
  module' <- GHC.peekCString utf8 =<< ccModule cc
  srcSpan <- GHC.peekCString utf8 =<< ccSrcSpan cc
  return $ "CostCentre " ++ label ++ " " ++ module' ++ " " ++ srcSpan
nomeata commented 2 years ago

The disassembler was never really finished, so consider it a proof of concept. That means, nothing in there is set in stone, and feel free to make changes as you see fit.

It's great to see new interest in it!