#3693: Show stack traces
---------------------------------+------------------------------------------
    Reporter:  jpet              |        Owner:              
        Type:  feature request   |       Status:  new         
    Priority:  normal            |    Milestone:  _|_         
   Component:  Runtime System    |      Version:  6.10.4      
    Keywords:                    |   Difficulty:              
          Os:  Unknown/Multiple  |     Testcase:              
Architecture:  Unknown/Multiple  |      Failure:  None/Unknown
       Patch:  0                 |  
---------------------------------+------------------------------------------
Changes (by batterseapower):

  * patch:  => 0


Comment:

 I've written a very simple patch to add support for basic STG stack
 traces.

 Here's how it looks:

 {{{
 $ cat Stacks2.hs
 module Main where

 main = thunk_use_site (myHead [])

 {-# NOINLINE thunk_use_site #-}
 thunk_use_site :: Bool -> IO ()
 thunk_use_site foo = case foo of True -> putStrLn "Woot!"

 {-# NOINLINE myHead #-}
 myHead (x:xs) = x

 $ ./Stacks2
 Stacks2: Stacks2.hs:10:1-17: Non-exhaustive patterns in function myHead

 Stacks2: Backtrace:
   main:Main.thunk_use_site1
   base:GHC.TopHandler.runMainIO1
 }}}

 It takes the approach of storing an optional string pointer in return
 closure info tables. Currently only frames arising from "case"
 scrutinisation are supported. The string generated from them contains
 information about the top-level function from which the "case" originated.

 There is a new primop, raiseWithStack#, and the catch# primop now supplies
 a ByteArray# to the exception handler, which contains an array of string
 pointers. This is reified into a [String] on the Haskell side, and shown
 to the user in the Haskell-side TopHandler.

 I changed the simplifier in one place to stop it generating new top-level
 names like "a", and instead basing those names on the binder the code
 originated from (if any). We could go through fixing such parts of the
 compiler on an ad-hoc basis, or we could implement something using HPC
 information to produce decent stack traces.

 This patch is pretty rough and ready and probably buggy, but I thought I'd
 throw it out there. Areas for improvement:

     * Reify other sorts of stack frame. In particular, allow the
 RetInfoTables generated by hand-written .cmm to contain strings, and show
 update frames. If we do this we should probably use [StackFrame] on the
 Haskell side rather than [String], where StackFrame is an algebraic type
 with a case for each kind of stack frame.
     * Better information about how the backtrace corresponds to the
 program the user wrote (e.g. using HPC as discussed above)
     * Common up stack frame strings. Currently, I'll emit the same string
 several times if there are multiple "case" expressions within one top
 level binding, which is going to contribute to bloat
     * Test it out. In particular, actually try running the test suite :-)

 One note: I repurposed some code from the IA64 branch of Adjustor.c to
 create my ByteArray#. However, it looks to me like the original code would
 not even compile (apparently allocate() has gained a Capability* argument
 since that code was written). Is the IA64 backend dead? If it's not, I've
 *certainly* broken it with this patch.

 Here are some rough-and-ready code bloat numbers. The base library before
 (approximately, this is another recent build I had lying around):

 {{{
 $ du .
 8.0K    ./autogen
 116K    ./cbits
 132K    ./Control/Concurrent
 112K    ./Control/Exception
  36K    ./Control/Monad/ST
  80K    ./Control/Monad
 780K    ./Control
  24K    ./Data/STRef
 2.6M    ./Data
  16K    ./Debug
 464K    ./Foreign/C
 184K    ./Foreign/Marshal
 876K    ./Foreign
 236K    ./GHC/IO/Encoding
 400K    ./GHC/IO/Handle
 1.3M    ./GHC/IO
 5.6M    ./GHC
  68K    ./System/Console
  44K    ./System/IO
  28K    ./System/Mem
 316K    ./System/Posix
 660K    ./System
 124K    ./Text/ParserCombinators
 144K    ./Text/Read
  16K    ./Text/Show
 404K    ./Text
 8.0K    ./Unsafe
  26M    .
 }}}

 And after:

 {{{
 $ du .
 8.0K    ./autogen
 116K    ./cbits
 148K    ./Control/Concurrent
 120K    ./Control/Exception
  36K    ./Control/Monad/ST
  80K    ./Control/Monad
 848K    ./Control
  24K    ./Data/STRef
 2.8M    ./Data
  16K    ./Debug
 472K    ./Foreign/C
 200K    ./Foreign/Marshal
 920K    ./Foreign
 244K    ./GHC/IO/Encoding
 460K    ./GHC/IO/Handle
 1.5M    ./GHC/IO
 6.3M    ./GHC
  80K    ./System/Console
  52K    ./System/IO
  32K    ./System/Mem
 332K    ./System/Posix
 712K    ./System
 132K    ./Text/ParserCombinators
 156K    ./Text/Read
  16K    ./Text/Show
 440K    ./Text
 8.0K    ./Unsafe
  30M    .
 }}}

 So a 15% increase in code size. Not too bad, especially considering there
 is room for improvement by commoning up some strings, as I outlined above.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3693#comment:11>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to