summaryrefslogtreecommitdiff
path: root/docs/users_guide/exts/callstack.rst
blob: f4fbf9b7e987dd01bdc071817b2a5accd8b111cd (plain)
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
146
.. _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 []     = errorWithCallStack "empty"
   myHead (x:xs) = x
 
   bad :: Int
   bad = myHead []
 
.. code-block:: none
 
   ghci> bad
   *** Exception: empty
   CallStack (from HasCallStack):
     errorWithCallStack, called at Bad.hs:8:15 in main:Bad
     myHead, called at Bad.hs:12:7 in main:Bad
 
includes the call-site of ``errorWithCallStack`` 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 ``errorWithCallStack`` line in
the printed stack is not particularly enlightening, so we might choose
to suppress it by freezing the ``CallStack`` that we pass to ``errorWithCallStack``. ::
 
   myHead :: HasCallStack => [a] -> a
   myHead []     = withFrozenCallStack (errorWithCallStack "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.