7f78a85c0cd200c97f908a607d762be92a54221c
[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 traceId :: String -> String
110 traceId a = trace a a
111
112 {-|
113 Like 'trace', but uses 'show' on the argument to convert it to a 'String'.
114
115 This makes it convenient for printing the values of interesting variables or
116 expressions inside a function. For example here we print the value of the
117 variables @x@ and @z@:
118
119 > f x y =
120 > traceShow (x, z) $ result
121 > where
122 > z = ...
123 > ...
124 -}
125 traceShow :: (Show a) => a -> b -> b
126 traceShow = trace . show
127
128 {-|
129 Like 'traceShow' but returns the shown value instead of a third value.
130 -}
131 traceShowId :: (Show a) => a -> a
132 traceShowId a = trace (show a) a
133
134 {-|
135 Like 'trace' but returning unit in an arbitrary monad. Allows for convenient
136 use in do-notation. Note that the application of 'trace' is not an action in the
137 monad, as 'traceIO' is in the 'IO' monad.
138
139 > ... = do
140 > x <- ...
141 > traceM $ "x: " ++ show x
142 > y <- ...
143 > traceM $ "y: " ++ show y
144 -}
145 traceM :: (Monad m) => String -> m ()
146 traceM string = trace string $ return ()
147
148 {-|
149 Like 'traceM', but uses 'show' on the argument to convert it to a 'String'.
150
151 > ... = do
152 > x <- ...
153 > traceMShow $ x
154 > y <- ...
155 > traceMShow $ x + y
156 -}
157 traceShowM :: (Show a, Monad m) => a -> m ()
158 traceShowM = traceM . show
159
160 -- | like 'trace', but additionally prints a call stack if one is
161 -- available.
162 --
163 -- In the current GHC implementation, the call stack is only
164 -- availble if the program was compiled with @-prof@; otherwise
165 -- 'traceStack' behaves exactly like 'trace'. Entries in the call
166 -- stack correspond to @SCC@ annotations, so it is a good idea to use
167 -- @-fprof-auto@ or @-fprof-auto-calls@ to add SCC annotations automatically.
168 --
169 traceStack :: String -> a -> a
170 traceStack str expr = unsafePerformIO $ do
171 traceIO str
172 stack <- currentCallStack
173 when (not (null stack)) $ traceIO (renderStack stack)
174 return expr
175
176
177 -- $eventlog_tracing
178 --
179 -- Eventlog tracing is a performance profiling system. These functions emit
180 -- extra events into the eventlog. In combination with eventlog profiling
181 -- tools these functions can be used for monitoring execution and
182 -- investigating performance problems.
183 --
184 -- Currently only GHC provides eventlog profiling, see the GHC user guide for
185 -- details on how to use it. These function exists for other Haskell
186 -- implementations but no events are emitted. Note that the string message is
187 -- always evaluated, whether or not profiling is available or enabled.
188
189 {-# NOINLINE traceEvent #-}
190 -- | The 'traceEvent' function behaves like 'trace' with the difference that
191 -- the message is emitted to the eventlog, if eventlog profiling is available
192 -- and enabled at runtime.
193 --
194 -- It is suitable for use in pure code. In an IO context use 'traceEventIO'
195 -- instead.
196 --
197 -- Note that when using GHC's SMP runtime, it is possible (but rare) to get
198 -- duplicate events emitted if two CPUs simultaneously evaluate the same thunk
199 -- that uses 'traceEvent'.
200 --
201 traceEvent :: String -> a -> a
202 traceEvent msg expr = unsafeDupablePerformIO $ do
203 traceEventIO msg
204 return expr
205
206 -- | The 'traceEventIO' function emits a message to the eventlog, if eventlog
207 -- profiling is available and enabled at runtime.
208 --
209 -- Compared to 'traceEvent', 'traceEventIO' sequences the event with respect to
210 -- other IO actions.
211 --
212 traceEventIO :: String -> IO ()
213 traceEventIO msg =
214 GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s ->
215 case traceEvent# p s of s' -> (# s', () #)
216
217 -- $markers
218 --
219 -- When looking at a profile for the execution of a program we often want to
220 -- be able to mark certain points or phases in the execution and see that
221 -- visually in the profile.
222
223 -- For example, a program might have several distinct phases with different
224 -- performance or resource behaviour in each phase. To properly interpret the
225 -- profile graph we really want to see when each phase starts and ends.
226 --
227 -- Markers let us do this: we can annotate the program to emit a marker at
228 -- an appropriate point during execution and then see that in a profile.
229 --
230 -- Currently this feature is only supported in GHC by the eventlog tracing
231 -- system, but in future it may also be supported by the heap profiling or
232 -- other profiling tools. These function exists for other Haskell
233 -- implementations but they have no effect. Note that the string message is
234 -- always evaluated, whether or not profiling is available or enabled.
235
236 {-# NOINLINE traceMarker #-}
237 -- | The 'traceMarker' function emits a marker to the eventlog, if eventlog
238 -- profiling is available and enabled at runtime. The @String@ is the name of
239 -- the marker. The name is just used in the profiling tools to help you keep
240 -- clear which marker is which.
241 --
242 -- This function is suitable for use in pure code. In an IO context use
243 -- 'traceMarkerIO' instead.
244 --
245 -- Note that when using GHC's SMP runtime, it is possible (but rare) to get
246 -- duplicate events emitted if two CPUs simultaneously evaluate the same thunk
247 -- that uses 'traceMarker'.
248 --
249 traceMarker :: String -> a -> a
250 traceMarker msg expr = unsafeDupablePerformIO $ do
251 traceMarkerIO msg
252 return expr
253
254 -- | The 'traceMarkerIO' function emits a marker to the eventlog, if eventlog
255 -- profiling is available and enabled at runtime.
256 --
257 -- Compared to 'traceMarker', 'traceMarkerIO' sequences the event with respect to
258 -- other IO actions.
259 --
260 traceMarkerIO :: String -> IO ()
261 traceMarkerIO msg =
262 GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s ->
263 case traceMarker# p s of s' -> (# s', () #)