summaryrefslogtreecommitdiff
path: root/libraries/ghc-heap/tests/TestUtils.hs
diff options
context:
space:
mode:
authorSven Tennie <sven.tennie@gmail.com>2023-05-08 18:29:32 +0000
committerSven Tennie <sven.tennie@gmail.com>2023-05-08 18:29:32 +0000
commite778d8320606726a820f7f351b87f94e0f5a9888 (patch)
tree000d130b73c71b71e58c550979cb8a3bcf1ab5c4 /libraries/ghc-heap/tests/TestUtils.hs
parent2c9f1a364f278299d2a89fb884c471d2d7883e8c (diff)
downloadhaskell-wip/decode_cloned_stack.tar.gz
ghc-heap: Decode StgStack and its stack frameswip/decode_cloned_stack
Previously, ghc-heap could only decode heap closures. The approach is explained in detail in note [Decoding the stack].
Diffstat (limited to 'libraries/ghc-heap/tests/TestUtils.hs')
-rw-r--r--libraries/ghc-heap/tests/TestUtils.hs53
1 files changed, 50 insertions, 3 deletions
diff --git a/libraries/ghc-heap/tests/TestUtils.hs b/libraries/ghc-heap/tests/TestUtils.hs
index 4f297cae3a..7193a4ac80 100644
--- a/libraries/ghc-heap/tests/TestUtils.hs
+++ b/libraries/ghc-heap/tests/TestUtils.hs
@@ -1,7 +1,54 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
-module TestUtils where
+{-# LANGUAGE UnliftedFFITypes #-}
-assertEqual :: (Show a, Eq a) => a -> a -> IO ()
+module TestUtils
+ ( assertEqual,
+ assertThat,
+ assertStackInvariants,
+ getDecodedStack,
+ unbox,
+ )
+where
+
+import Control.Monad.IO.Class
+import Data.Array.Byte
+import Data.Foldable
+import Debug.Trace
+import GHC.Exts
+import GHC.Exts.Heap
+import GHC.Exts.Heap.Closures
+import GHC.Exts.Stack.Decode
+import GHC.Records
+import GHC.Stack (HasCallStack)
+import GHC.Stack.CloneStack
+import Unsafe.Coerce (unsafeCoerce)
+
+getDecodedStack :: IO (StackSnapshot, [StackFrame])
+getDecodedStack = do
+ stack <- cloneMyStack
+ stackClosure <- decodeStack stack
+
+ pure (stack, ssc_stack stackClosure)
+
+assertEqual :: (HasCallStack, Monad m, Show a, Eq a) => a -> a -> m ()
assertEqual a b
| a /= b = error (show a ++ " /= " ++ show b)
- | otherwise = return ()
+ | otherwise = pure ()
+
+assertThat :: (HasCallStack, Monad m) => String -> (a -> Bool) -> a -> m ()
+assertThat s f a = if f a then pure () else error s
+
+assertStackInvariants :: (HasCallStack, MonadIO m) => [StackFrame] -> m ()
+assertStackInvariants decodedStack =
+ assertThat
+ "Last frame is stop frame"
+ ( \case
+ StopFrame info -> tipe info == STOP_FRAME
+ _ -> False
+ )
+ (last decodedStack)
+
+unbox :: Box -> IO Closure
+unbox = getBoxedClosureData