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