[GHC] #11047: Provide call stacks in GHCi
GHC
ghc-devs at haskell.org
Sun Nov 1 21:30:54 UTC 2015
#11047: Provide call stacks in GHCi
-------------------------------------+-------------------------------------
Reporter: simonmar | Owner: simonmar
Type: task | Status: new
Priority: high | Milestone: 8.0.1
Component: GHCi | Version: 7.11
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets: #545, #4837
Differential Rev(s): Phab:D1407 | Wiki Page:
-------------------------------------+-------------------------------------
I want call stacks to be available in GHCi with no effort on the part of
the user, or changes to the source code. The call stack will be available
both programatically and via GHCi commands:
* `GHC.Stack.currentCallStack` returns the current call stack as
`[String]`. This can be used from `error` and copied into the exception
string.
* `Debug.Trace.traceStack` prints out the stack anywhere.
* GHCi will have a new command `:where` to print out the stack when
stopped at a breakpoint
The stack trace will be the accurate (i.e. not exposing details of lazy
evaluation or tail calls) and detailed (including locations of calls, not
just the enclosing function definition).
= Implmeentation =
Here's how it's going to work:
* We make GHCi work with profiling (done: Phab:D1407)
* We make breakpoint ticks behave like SCC annotations, and update the
interpreter to implement the cost-centre-stack semantics.
= Exmaple =
Here's an example from my prototype:
{{{
g :: Int -> [Int]
g n = traceStack "g" [n]
h :: Int -> Bool
h n = case g n of
[] -> True
(x:xs) -> False
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
k n = map h [n]
}}}
{{{
[1 of 1] Compiling Main ( /home/smarlow/scratch/dbg1.hs,
interpreted )
Ok, modules loaded: Main.
*Main> k 1
[g
Stack trace:
Main.g (/home/smarlow/scratch/dbg1.hs:13:7-24)
Main.g (/home/smarlow/scratch/dbg1.hs:13:1-24)
Main.h (/home/smarlow/scratch/dbg1.hs:16:12-14)
Main.h (/home/smarlow/scratch/dbg1.hs:(16,7)-(18,24))
Main.h (/home/smarlow/scratch/dbg1.hs:(16,1)-(18,24))
Main.map (/home/smarlow/scratch/dbg1.hs:22:16-18)
Main.map (/home/smarlow/scratch/dbg1.hs:22:16-29)
Main.map (/home/smarlow/scratch/dbg1.hs:(21,1)-(22,29))
Main.k (/home/smarlow/scratch/dbg1.hs:24:7-15)
Main.k (/home/smarlow/scratch/dbg1.hs:24:1-15)
False]
*Main>
}}}
We could trim some of the extra detail from the stack trace so that each
function appears once; there are several choices here, currently I'm
collecting and displaying the most detail.
= Deployment =
One disadvantage of this is that it requires GHCi to be built with
profiling, and all the libraries have to be built with profiling too.
There are two options for deployment:
1. We deploy two versions of GHCi (profiled and non-profiled), or
2. We expand on what GHCJS did, and make the interpreted code run in a
separate process, thus separating the GHCi binary itself from the code
being interpreted. This would allow the interpreted code to be run with
the profiled RTS while GHCi itself is unprofiled.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11047>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list