Remove GHC.Exts.traceEventIO
[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, -- :: String -> a -> a
25 traceShow,
26 traceStack,
27 traceIO, -- :: String -> IO ()
28 putTraceMsg,
29
30 -- * Eventlog tracing
31 -- $eventlog_tracing
32 traceEvent,
33 traceEventIO,
34 ) where
35
36 import Prelude
37 import System.IO.Unsafe
38 import Control.Monad
39
40 #ifdef __GLASGOW_HASKELL__
41 import Foreign.C.String
42 import GHC.Base
43 import qualified GHC.Foreign
44 import GHC.IO.Encoding
45 import GHC.Ptr
46 import GHC.Stack
47 #else
48 import System.IO (hPutStrLn,stderr)
49 #endif
50
51 -- $tracing
52 --
53 -- The 'trace', 'traceShow' and 'traceIO' functions print messages to an output
54 -- stream. They are intended for \"printf debugging\", that is: tracing the flow
55 -- of execution and printing interesting values.
56
57 -- The usual output stream is 'System.IO.stderr'. For Windows GUI applications
58 -- (that have no stderr) the output is directed to the Windows debug console.
59 -- Some implementations of these functions may decorate the string that\'s
60 -- output to indicate that you\'re tracing.
61
62 -- | The 'traceIO' function outputs the trace message from the IO monad.
63 -- This sequences the output with respect to other IO actions.
64 --
65 traceIO :: String -> IO ()
66 traceIO msg = do
67 #ifndef __GLASGOW_HASKELL__
68 hPutStrLn stderr msg
69 #else
70 withCString "%s\n" $ \cfmt ->
71 withCString msg $ \cmsg ->
72 debugBelch cfmt cmsg
73
74 -- don't use debugBelch() directly, because we cannot call varargs functions
75 -- using the FFI.
76 foreign import ccall unsafe "HsBase.h debugBelch2"
77 debugBelch :: CString -> CString -> IO ()
78 #endif
79
80
81 -- | Deprecated. Use 'traceIO'.
82 putTraceMsg :: String -> IO ()
83 putTraceMsg = traceIO
84 {-# DEPRECATED putTraceMsg "Use Debug.Trace.traceIO" #-}
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 uses 'show' on the argument to convert it to a 'String'.
108
109 This makes it convenient for printing the values of interesting variables or
110 expressions inside a function. For example here we print the value of the
111 variables @x@ and @z@:
112
113 > f x y =
114 > traceShow (x, z) $ result
115 > where
116 > z = ...
117 > ...
118 -}
119 traceShow :: (Show a) => a -> b -> b
120 traceShow = trace . show
121
122
123 -- $eventlog_tracing
124 --
125 -- Eventlog tracing is a performance profiling system. These functions emit
126 -- extra events into the eventlog. In combination with eventlog profiling
127 -- tools these functions can be used for monitoring execution and
128 -- investigating performance problems.
129 --
130 -- Currently only GHC provides eventlog profiling, see the GHC user guide for
131 -- details on how to use it. These function exists for other Haskell
132 -- implementations but no events are emitted. Note that the string message is
133 -- always evaluated, whether or not profiling is available or enabled.
134
135 {-# NOINLINE traceEvent #-}
136 -- | The 'traceEvent' function behaves like 'trace' with the difference that
137 -- the message is emitted to the eventlog, if eventlog profiling is available
138 -- and enabled at runtime.
139 --
140 -- It is suitable for use in pure code. In an IO context use 'traceEventIO'
141 -- instead.
142 --
143 -- Note that when using GHC's SMP runtime, it is possible (but rare) to get
144 -- duplicate events emitted if two CPUs simultaneously evaluate the same thunk
145 -- that uses 'traceEvent'.
146 --
147 traceEvent :: String -> a -> a
148 traceEvent msg expr = unsafeDupablePerformIO $ do
149 traceEventIO msg
150 return expr
151
152 -- | The 'traceEventIO' function emits a message to the eventlog, if eventlog
153 -- profiling is available and enabled at runtime.
154 --
155 -- Compared to 'traceEvent', 'traceEventIO' sequences the event with respect to
156 -- other IO actions.
157 --
158 traceEventIO :: String -> IO ()
159 #ifdef __GLASGOW_HASKELL__
160 traceEventIO msg =
161 GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s ->
162 case traceEvent# p s of s' -> (# s', () #)
163 #else
164 traceEventIO msg = (return $! length msg) >> return ()
165 #endif
166
167 -- | like 'trace', but additionally prints a call stack if one is
168 -- available.
169 --
170 -- In the current GHC implementation, the call stack is only
171 -- availble if the program was compiled with @-prof@; otherwise
172 -- 'traceStack' behaves exactly like 'trace'. Entries in the call
173 -- stack correspond to @SCC@ annotations, so it is a good idea to use
174 -- @-fprof-auto@ or @-fprof-auto-calls@ to add SCC annotations automatically.
175 --
176 traceStack :: String -> a -> a
177 traceStack str expr = unsafePerformIO $ do
178 traceIO str
179 stack <- currentCallStack
180 when (not (null stack)) $ traceIO (renderStack stack)
181 return expr