diff options
author | Sven Tennie <sven.tennie@gmail.com> | 2023-05-08 18:29:32 +0000 |
---|---|---|
committer | Sven Tennie <sven.tennie@gmail.com> | 2023-05-08 18:29:32 +0000 |
commit | e778d8320606726a820f7f351b87f94e0f5a9888 (patch) | |
tree | 000d130b73c71b71e58c550979cb8a3bcf1ab5c4 /libraries/ghc-heap/tests/stack_underflow.hs | |
parent | 2c9f1a364f278299d2a89fb884c471d2d7883e8c (diff) | |
download | haskell-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/stack_underflow.hs')
-rw-r--r-- | libraries/ghc-heap/tests/stack_underflow.hs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/libraries/ghc-heap/tests/stack_underflow.hs b/libraries/ghc-heap/tests/stack_underflow.hs new file mode 100644 index 0000000000..7da5fb1d34 --- /dev/null +++ b/libraries/ghc-heap/tests/stack_underflow.hs @@ -0,0 +1,49 @@ +{-# LANGUAGE RecordWildCards #-} + +module Main where + +import Control.Monad +import Data.Bool (Bool (True)) +import GHC.Exts.Heap +import GHC.Exts.Heap.ClosureTypes +import GHC.Exts.Heap.Closures +import GHC.Exts.Heap.InfoTable.Types +import GHC.Exts.Stack.Decode +import GHC.Stack (HasCallStack) +import GHC.Stack.CloneStack +import TestUtils + +main = loop 256 + +{-# NOINLINE loop #-} +loop 0 = Control.Monad.void getStack +loop n = print "x" >> loop (n - 1) >> print "x" + +getStack :: HasCallStack => IO () +getStack = do + (s, decodedStack) <- getDecodedStack + assertStackInvariants decodedStack + assertThat + "Stack contains underflow frames" + (== True) + (any isUnderflowFrame decodedStack) + assertStackChunksAreDecodable decodedStack + return () + +isUnderflowFrame :: StackFrame -> Bool +isUnderflowFrame (UnderflowFrame {..}) = tipe info_tbl == UNDERFLOW_FRAME +isUnderflowFrame _ = False + +assertStackChunksAreDecodable :: HasCallStack => [StackFrame] -> IO () +assertStackChunksAreDecodable s = do + let underflowFrames = filter isUnderflowFrame s + assertThat + ("Expect some underflow frames. Got " ++ show (length underflowFrames)) + (>= 2) + (length underflowFrames) + let stackFrames = map (ssc_stack . nextChunk) underflowFrames + assertThat + "No empty stack chunks" + (== True) + ( not (any null stackFrames) + ) |