a857760deec2585756708284a51b029a784401a8
[packages/base.git] / Debug / Trace.hs
1 {-# LANGUAGE Unsafe #-}
2 {-# LANGUAGE ForeignFunctionInterface, MagicHash, UnboxedTuples #-}
3
4 -----------------------------------------------------------------------------
5 -- |
6 -- Module : Debug.Trace
7 -- Copyright : (c) The University of Glasgow 2001
8 -- License : BSD-style (see the file libraries/base/LICENSE)
9 --
10 -- Maintainer : libraries@haskell.org
11 -- Stability : provisional
12 -- Portability : portable
13 --
14 -- Functions for tracing and monitoring execution.
15 --
16 -- These can be useful for investigating bugs or performance problems.
17 -- They should /not/ be used in production code.
18 --
19 -----------------------------------------------------------------------------
20
21 module Debug.Trace (
22 -- * Tracing
23 -- $tracing
24 trace,
25 traceId,
26 traceShow,
27 traceShowId,
28 traceStack,
29 traceIO,
30 traceM,
31 traceShowM,
32 putTraceMsg,
33
34 -- * Eventlog tracing
35 -- $eventlog_tracing
36 traceEvent,
37 traceEventIO,
38
39 -- * Execution phase markers
40 -- $markers
41 traceMarker,
42 traceMarkerIO,
43 ) where
44
45 import Prelude
46 import System.IO.Unsafe
47 import Control.Monad
48
49 import Foreign.C.String
50 import GHC.Base
51 import qualified GHC.Foreign
52 import GHC.IO.Encoding
53 import GHC.Ptr
54 import GHC.Stack
55
56 -- $tracing
57 --
58 -- The 'trace', 'traceShow' and 'traceIO' functions print messages to an output
59 -- stream. They are intended for \"printf debugging\", that is: tracing the flow
60 -- of execution and printing interesting values.
61
62 -- The usual output stream is 'System.IO.stderr'. For Windows GUI applications
63 -- (that have no stderr) the output is directed to the Windows debug console.
64 -- Some implementations of these functions may decorate the string that\'s
65 -- output to indicate that you\'re tracing.
66
67 -- | The 'traceIO' function outputs the trace message from the IO monad.
68 -- This sequences the output with respect to other IO actions.
69 --
70 traceIO :: String -> IO ()
71 traceIO msg = do
72 withCString "%s\n" $ \cfmt ->
73 withCString msg $ \cmsg ->
74 debugBelch cfmt cmsg
75
76 -- don't use debugBelch() directly, because we cannot call varargs functions
77 -- using the FFI.
78 foreign import ccall unsafe "HsBase.h debugBelch2"
79 debugBelch :: CString -> CString -> IO ()
80
81 -- | Deprecated. Use 'traceIO'.
82 putTraceMsg :: String -> IO ()
83 putTraceMsg = traceIO
84 {-# DEPRECATED putTraceMsg "Use Debug.Trace.traceIO" #-} -- deprecated in 7.4
85
86
87 {-# NOINLINE trace #-}
88 {-|
89 The 'trace' function outputs the trace message given as its first argument,
90 before returning the second argument as its result.
91
92 For example, this returns the value of @f x@ but first outputs the message.
93
94 > trace ("calling f with x = " ++ show x) (f x)
95
96 The 'trace' function should /only/ be used for debugging, or for monitoring
97 execution. The function is not referentially transparent: its type indicates
98 that it is a pure function but it has the side effect of outputting the
99 trace message.
100 -}
101 trace :: String -> a -> a
102 trace string expr = unsafePerformIO $ do
103 traceIO string
104 return expr
105
106 {-|
107 Like 'trace' but returns the message instead of a third value.
108
109 /Since: 4.7.0.0/
110 -}
111 traceId :: String -> String
112 traceId a = trace a a
113
114 {-|
115 Like 'trace', but uses 'show' on the argument to convert it to a 'String'.
116
117 This makes it convenient for printing the values of interesting variables or
118 expressions inside a function. For example here we print the value of the
119 variables @x@ and @z@:
120
121 > f x y =
122 > traceShow (x, z) $ result
123 > where
124 > z = ...
125 > ...
126 -}
127 traceShow :: (Show a) => a -> b -> b
128 traceShow = trace . show
129
130 {-|
131 Like 'traceShow' but returns the shown value instead of a third value.
132
133 /Since: 4.7.0.0/
134 -}
135 traceShowId :: (Show a) => a -> a
136 traceShowId a = trace (show a) a
137
138 {-|
139 Like 'trace' but returning unit in an arbitrary monad. Allows for convenient
140 use in do-notation. Note that the application of 'trace' is not an action in the
141 monad, as 'traceIO' is in the 'IO' monad.
142
143 > ... = do
144 > x <- ...
145 > traceM $ "x: " ++ show x
146 > y <- ...
147 > traceM $ "y: " ++ show y
148
149 /Since: 4.7.0.0/
150 -}
151 traceM :: (Monad m) => String -> m ()
152 traceM string = trace string $ return ()
153
154 {-|
155 Like 'traceM', but uses 'show' on the argument to convert it to a 'String'.
156
157 > ... = do
158 > x <- ...
159 > traceMShow $ x
160 > y <- ...
161 > traceMShow $ x + y
162
163 /Since: 4.7.0.0/
164 -}
165 traceShowM :: (Show a, Monad m) => a -> m ()
166 traceShowM = traceM . show
167
168 -- | like 'trace', but additionally prints a call stack if one is
169 -- available.
170 --
171 -- In the current GHC implementation, the call stack is only
172 -- availble if the program was compiled with @-prof@; otherwise
173 -- 'traceStack' behaves exactly like 'trace'. Entries in the call
174 -- stack correspond to @SCC@ annotations, so it is a good idea to use
175 -- @-fprof-auto@ or @-fprof-auto-calls@ to add SCC annotations automatically.
176 --
177 traceStack :: String -> a -> a
178 traceStack str expr = unsafePerformIO $ do
179 traceIO str
180 stack <- currentCallStack
181 when (not (null stack)) $ traceIO (renderStack stack)
182 return expr
183
184
185 -- $eventlog_tracing
186 --
187 -- Eventlog tracing is a performance profiling system. These functions emit
188 -- extra events into the eventlog. In combination with eventlog profiling
189 -- tools these functions can be used for monitoring execution and
190 -- investigating performance problems.
191 --
192 -- Currently only GHC provides eventlog profiling, see the GHC user guide for
193 -- details on how to use it. These function exists for other Haskell
194 -- implementations but no events are emitted. Note that the string message is
195 -- always evaluated, whether or not profiling is available or enabled.
196
197 {-# NOINLINE traceEvent #-}
198 -- | The 'traceEvent' function behaves like 'trace' with the difference that
199 -- the message is emitted to the eventlog, if eventlog profiling is available
200 -- and enabled at runtime.
201 --
202 -- It is suitable for use in pure code. In an IO context use 'traceEventIO'
203 -- instead.
204 --
205 -- Note that when using GHC's SMP runtime, it is possible (but rare) to get
206 -- duplicate events emitted if two CPUs simultaneously evaluate the same thunk
207 -- that uses 'traceEvent'.
208 --
209 traceEvent :: String -> a -> a
210 traceEvent msg expr = unsafeDupablePerformIO $ do
211 traceEventIO msg
212 return expr
213
214 -- | The 'traceEventIO' function emits a message to the eventlog, if eventlog
215 -- profiling is available and enabled at runtime.
216 --
217 -- Compared to 'traceEvent', 'traceEventIO' sequences the event with respect to
218 -- other IO actions.
219 --
220 traceEventIO :: String -> IO ()
221 traceEventIO msg =
222 GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s ->
223 case traceEvent# p s of s' -> (# s', () #)
224
225 -- $markers
226 --
227 -- When looking at a profile for the execution of a program we often want to
228 -- be able to mark certain points or phases in the execution and see that
229 -- visually in the profile.
230
231 -- For example, a program might have several distinct phases with different
232 -- performance or resource behaviour in each phase. To properly interpret the
233 -- profile graph we really want to see when each phase starts and ends.
234 --
235 -- Markers let us do this: we can annotate the program to emit a marker at
236 -- an appropriate point during execution and then see that in a profile.
237 --
238 -- Currently this feature is only supported in GHC by the eventlog tracing
239 -- system, but in future it may also be supported by the heap profiling or
240 -- other profiling tools. These function exists for other Haskell
241 -- implementations but they have no effect. Note that the string message is
242 -- always evaluated, whether or not profiling is available or enabled.
243
244 {-# NOINLINE traceMarker #-}
245 -- | The 'traceMarker' function emits a marker to the eventlog, if eventlog
246 -- profiling is available and enabled at runtime. The @String@ is the name of
247 -- the marker. The name is just used in the profiling tools to help you keep
248 -- clear which marker is which.
249 --
250 -- This function is suitable for use in pure code. In an IO context use
251 -- 'traceMarkerIO' instead.
252 --
253 -- Note that when using GHC's SMP runtime, it is possible (but rare) to get
254 -- duplicate events emitted if two CPUs simultaneously evaluate the same thunk
255 -- that uses 'traceMarker'.
256 --
257 -- /Since: 4.7.0.0/
258 traceMarker :: String -> a -> a
259 traceMarker msg expr = unsafeDupablePerformIO $ do
260 traceMarkerIO msg
261 return expr
262
263 -- | The 'traceMarkerIO' function emits a marker to the eventlog, if eventlog
264 -- profiling is available and enabled at runtime.
265 --
266 -- Compared to 'traceMarker', 'traceMarkerIO' sequences the event with respect to
267 -- other IO actions.
268 --
269 -- /Since: 4.7.0.0/
270 traceMarkerIO :: String -> IO ()
271 traceMarkerIO msg =
272 GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s ->
273 case traceMarker# p s of s' -> (# s', () #)