error stack traces/source locations (was: Should exhaustiveness
testing be on by default?)
Claus Reinke
claus.reinke at talk21.com
Sat May 23 18:34:20 EDT 2009
> What is really frustrating is that GHC has the machinery to do this
> trivially (RULES, soon core2core phase plugins as well), only that this machinery gets applied
> when source location information is no longer available, so it is useless for this problem:-(
I'd be happy to be proven wrong in this, of course!-) I had the feeling
that there'd been some recent work on all this and, indeed, reddit has:
http://www.reddit.com/r/haskell/comments/8mbar/finding_the_needle_stack_traces_for_ghc_pdf/
Right on topic, and I assume the authors are on this list!-) It appears
that the bulk of the paper is concerned with performance improvements -
if we just want to recreate the user view, the mapException approach
would appear to be a lot simpler (perhaps the paper could discuss it
as a poor man's alternative, in particular since its source rewrites seem
less intrusive?).
Of course, having any support for this in GHC will be an improvement.
However, it is interesting that the paper suggests an implementation
using a core2core transformation, *with access to source location l*:
[|x_l|]s = x deb (push l s), if x has (Debugged ’x deb) ann
(Figure 1, page 4)
Does that mean it would be possible to add an extension to RULES
that would allow things like:
{-# RULES "f->f_" forall x. f{SRCLOC} x = mapError SRCLOC (f_ x) #-}
ie, referring to the source location of 'f' in the right hand side? That
would seem to be the smallest possible change permitting a user-level
implementation of error stack traces. And it might be more generally
useful as well.
Attached is another example source, again doing the expansion by hand
( (f x) -> mapError SRCLOC (f x); error ".." -> errorSrc SRCLOC "..")
and relying on mapException to collect the traces, with a few recursive
examples suggested by the paper, and three variations of eliding recursive
call sites from the stack traces (note that this only elides when presenting
the trace, the real implementation from the paper elides when
constructing the trace).
Claus
------------------------------------ example output:
$ ghc -e main stacktraces.hs -DPLAIN
-- fib 5
fib with non-positive number: 0
("stacktraces.hs",46)
("stacktraces.hs",45)
("stacktraces.hs",45)
("stacktraces.hs",45)
("stacktraces.hs",45)
("stacktraces.hs",36)
-- odd_ 5
odd_: no match
("stacktraces.hs",51)
("stacktraces.hs",54)
("stacktraces.hs",50)
("stacktraces.hs",54)
("stacktraces.hs",50)
("stacktraces.hs",38)
-- firstLetters2
Prelude.head: empty list
("stacktraces.hs",58)
("stacktraces.hs",62)
("stacktraces.hs",62)
("stacktraces.hs",62)
$ ghc -e main stacktraces.hs
-- fib 5
fib with non-positive number: 0
("stacktraces.hs",46)
...
("stacktraces.hs",45)
("stacktraces.hs",36)
-- odd_ 5
odd_: no match
("stacktraces.hs",51)
...
("stacktraces.hs",54)
("stacktraces.hs",50)
("stacktraces.hs",38)
-- firstLetters2
Prelude.head: empty list
("stacktraces.hs",58)
...
("stacktraces.hs",62)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: stacktraces.hs
Type: application/octet-stream
Size: 3248 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/glasgow-haskell-users/attachments/20090523/4c0ed3f1/stacktraces.obj
More information about the Glasgow-haskell-users
mailing list