1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
.. _hascallstack:
HasCallStack
============
``GHC.Stack.HasCallStack`` is a lightweight method of obtaining a
partial call-stack at any point in the program.
A function can request its call-site with the ``HasCallStack`` constraint
and access it as a Haskell value by using ``callStack``.
One can then use functions from ``GHC.Stack`` to inspect or pretty
print (as is done in ``f`` below) the call stack. ::
f :: HasCallStack => IO ()
f = putStrLn (prettyCallStack callStack)
g :: HasCallStack => IO ()
g = f
Evaluating ``f`` directly shows a call stack with a single entry,
while evaluating ``g``, which also requests its call-site, shows
two entries, one for each computation "annotated" with
``HasCallStack``.
.. code-block:: none
ghci> f
CallStack (from HasCallStack):
f, called at <interactive>:19:1 in interactive:Ghci1
ghci> g
CallStack (from HasCallStack):
f, called at <interactive>:17:5 in main:Main
g, called at <interactive>:20:1 in interactive:Ghci2
The ``error`` function from the Prelude supports printing the call stack that
led to the error in addition to the usual error message:
.. code-block:: none
ghci> error "bad"
*** Exception: bad
CallStack (from HasCallStack):
error, called at <interactive>:25:1 in interactive:Ghci5
The call stack here consists of a single entry, pinpointing the source
of the call to ``error``. However, by annotating several computations
with ``HasCallStack``, figuring out the exact circumstances and sequences
of calls that lead to a call to ``error`` becomes a lot easier, as demonstrated
with the simple example below. ::
f :: HasCallStack => IO ()
f = error "bad bad bad"
g :: HasCallStack => IO ()
g = f
h :: HasCallStack => IO ()
h = g
.. code-block:: none
ghci> h
*** Exception: bad bad bad
CallStack (from HasCallStack):
error, called at call-stack.hs:4:5 in main:Main
f, called at call-stack.hs:7:5 in main:Main
g, called at call-stack.hs:10:5 in main:Main
h, called at <interactive>:28:1 in interactive:Ghci1
The ``CallStack`` will only extend as far as the types allow it, for
example ::
myHead :: HasCallStack => [a] -> a
myHead [] = error "empty"
myHead (x:xs) = x
bad :: Int
bad = myHead []
.. code-block:: none
ghci> bad
*** Exception: empty
CallStack (from HasCallStack):
error, called at Bad.hs:8:15 in main:Bad
myHead, called at Bad.hs:12:7 in main:Bad
includes the call-site of ``error`` in ``myHead``, and of ``myHead`` in
``bad``, but not the call-site of ``bad`` at the GHCi prompt.
GHC solves ``HasCallStack`` constraints in two steps:
1. If there is a ``CallStack`` in scope -- i.e. the enclosing definition
has a ``HasCallStack`` constraint -- GHC will push the new call-site
onto the existing ``CallStack``.
2. Otherwise GHC will solve the ``HasCallStack`` constraint for the
singleton ``CallStack`` containing just the current call-site.
Importantly, GHC will **never** infer a ``HasCallStack`` constraint,
you must request it explicitly.
``CallStack`` is kept abstract, but GHC provides a function ::
getCallStack :: CallStack -> [(String, SrcLoc)]
to access the individual call-sites in the stack. The ``String`` is the
name of the function that was called, and the ``SrcLoc`` provides the
package, module, and file name, as well as the line and column numbers.
``GHC.Stack`` additionally exports a function ``withFrozenCallStack`` that
allows users to freeze the current ``CallStack``, preventing any future push
operations from having an effect. This can be used by library authors
to prevent ``CallStack``\s from exposing unnecessary implementation
details. Consider the ``myHead`` example above, the ``error`` line in the
printed stack is not particularly enlightening, so we might choose to suppress
it by freezing the ``CallStack`` that we pass to ``error``. ::
myHead :: HasCallStack => [a] -> a
myHead [] = withFrozenCallStack (error "empty")
myHead (x:xs) = x
.. code-block:: none
ghci> myHead []
*** Exception: empty
CallStack (from HasCallStack):
myHead, called at Bad.hs:12:7 in main:Bad
**NOTE**: The intrepid user may notice that ``HasCallStack`` is just an
alias for an implicit parameter ``?callStack :: CallStack``. This is an
implementation detail and **should not** be considered part of the
``CallStack`` API, we may decide to change the implementation in the
future.
Compared with other sources of stack traces
-------------------------------------------
``HasCallStack`` does not interact with the RTS and does not require
compilation with ``-prof``. On the other hand, as the ``CallStack`` is
built up explicitly via the ``HasCallStack`` constraints, it will
generally not contain as much information as the simulated call-stacks
maintained by the RTS.
|