@@ -94,9 +94,14 @@ module Control.Distributed.Process.Debug
94 , disableTrace
94 , disableTrace
95 , disableTraceAsync
95 , disableTraceAsync
96 , withTracer
96 , withTracer
97 , setTraceFlags
99 , setTraceFlags
98 , setTraceFlagsAsync
100 , setTraceFlagsAsync
99 , defaultTraceFlags
101 , defaultTraceFlags
100 -- * Debugging
105 -- * Debugging
101 , startTracer
106 , startTracer
102 , stopTracer
107 , stopTracer
@@ -128,6 +133,7 @@ import Control.Distributed.Process.Internal.Primitives
128 , finally
133 , finally
130 , monitor
135 , monitor
132import Control.Distributed.Process.Internal.Types
138import Control.Distributed.Process.Internal.Types
133 ( Tracer(..)
139 ( Tracer(..)
@@ -161,6 +167,10 @@ import qualified Control.Distributed.Process.Internal.Trace.Primitives as Tracer
161 , disableTraceSync
167 , disableTraceSync
162 , setTraceFlags
168 , setTraceFlags
163 , setTraceFlagsSync
169 , setTraceFlagsSync
165import Control.Distributed.Process.Node
175import Control.Distributed.Process.Node
166import Control.Distributed.Process.Serializable
176import Control.Distributed.Process.Serializable
@@ -189,7 +199,6 @@ import Prelude hiding (catch)
189-- reregister the original (prior) tracer pid before terminating.
199-- reregister the original (prior) tracer pid before terminating.
190startTracer :: (TraceEvent -> Process ()) -> Process ProcessId
200startTracer :: (TraceEvent -> Process ()) -> Process ProcessId
191startTracer handler = do
201startTracer handler = do
193 withRegisteredTracer $ \pid -> do
202 withRegisteredTracer $ \pid -> do
194 node <- processNode <$> ask
203 node <- processNode <$> ask
195 newPid <- liftIO $ forkProcess node $ do
204 newPid <- liftIO $ forkProcess node $ do
@@ -200,9 +209,8 @@ startTracer handler = do
200 -- close succession, due to scheduling
209 -- close succession, due to scheduling
201 finally (traceProxy pid handler)
210 finally (traceProxy pid handler)
202 (resetTracer pid)
211 (resetTracer pid)
203− enableTrace newPid
212+ enableTrace newPid -- invokes sync + registration
204− sendChan sp newPid
213+ return newPid
207-- | Evaluate @proc@ with tracing enabled via @handler@, and immediately
215-- | Evaluate @proc@ with tracing enabled via @handler@, and immediately
208-- disable tracing thereafter, before giving the result (or exception
216-- disable tracing thereafter, before giving the result (or exception
@@ -212,22 +220,38 @@ withTracer :: forall a.
212 -> Process a
220 -> Process a
213 -> Process (Either SomeException a)
221 -> Process (Either SomeException a)
214withTracer handler proc = do
222withTracer handler proc = do
223+ say "starting new tracer"
215 tracer <- startTracer handler
224 tracer <- startTracer handler
216− finally (try proc)
225+ finally (try ((say "evaluating tracer proc...") >> proc))
217 (stopTracing tracer)
226 (stopTracing tracer)
219 stopTracing :: ProcessId -> Process ()
228 stopTracing :: ProcessId -> Process ()
220 stopTracing tracer = do
229 stopTracing tracer = do
230+ say "stopping tracer"
221 ref <- monitor tracer
231 ref <- monitor tracer
222 stopTracer
232 stopTracer
223 receiveWait [
233 receiveWait [
224 matchIf (\(ProcessMonitorNotification ref' _ _) -> ref == ref')
234 matchIf (\(ProcessMonitorNotification ref' _ _) -> ref == ref')
225 (\_ -> return ())
235 (\_ -> return ())
239+-- | Evaluate @proc@ with the supplied flags enabled. Any previously set
240+-- flags are restored immediately afterwards.
241+withFlags :: forall a.
244+ -> Process (Either SomeException a)
245+withFlags flags proc = do
247+ withLocalTracer $ \t -> liftIO $ Tracer.getTraceFlags t sp
248+ oldFlags <- receiveChan rp
249+ finally (setTraceFlags flags >> try proc)
250+ (setTraceFlags oldFlags >> say "exit withFlags")
228traceProxy :: ProcessId -> (TraceEvent -> Process ()) -> Process ()
252traceProxy :: ProcessId -> (TraceEvent -> Process ()) -> Process ()
229traceProxy pid act = do
253traceProxy pid act = do
230− getSelfPid >>= reregister "tracer" -- registration is synchronous
254+ say "tracing has started"
231 proxy pid $ \(ev :: TraceEvent) ->
255 proxy pid $ \(ev :: TraceEvent) ->
232 case ev of
256 case ev of
233 (TraceEvTakeover _) -> die "takeover"
257 (TraceEvTakeover _) -> die "takeover"
@@ -235,7 +259,9 @@ traceProxy pid act = do
235 _ -> act ev >> return True
259 _ -> act ev >> return True
237resetTracer :: ProcessId -> Process ()
261resetTracer :: ProcessId -> Process ()
263+ say $ "resetting trace to " ++ (show pid)
238−resetTracer pid = enableTrace pid
264+ enableTrace pid
240-- | Stops a user supplied tracer started with 'startTracer'.
266-- | Stops a user supplied tracer started with 'startTracer'.
241-- Note that only one tracer process can be active at any given time.
267-- Note that only one tracer process can be active at any given time.
@@ -252,19 +278,17 @@ resetTracer pid = enableTrace pid
252-- If tracing is support disabled for the node, this function will also
278-- If tracing is support disabled for the node, this function will also
253-- have no effect.
279-- have no effect.
254stopTracer :: Process ()
280stopTracer :: Process ()
255−stopTracer = withLocalTracer $ \t ->
281+stopTracer =
257− InactiveTracer -> return ()
258− (ActiveTracer _ _) -> withRegisteredTracer $ \pid -> do
282+ withRegisteredTracer $ \pid -> do
259− -- we need to avoid killing the initial (base) tracer, as
283+ -- we need to avoid killing the initial (base) tracer, as
260− -- nothing we rely on having exactly 1 registered tracer
284+ -- nothing we rely on having exactly 1 registered tracer
261− -- process at all times!
285+ -- process at all times!
262− basePid <- whereis "tracer.initial"
286+ basePid <- whereis "tracer.initial"
263− case basePid == (Just pid) of
287+ case basePid == (Just pid) of
264− True -> return ()
288+ True -> return ()
265− False -> send pid TraceEvDisable
289+ False -> send pid TraceEvDisable
267−withRegisteredTracer :: (ProcessId -> Process ()) -> Process ()
291+withRegisteredTracer :: (ProcessId -> Process a) -> Process a
268withRegisteredTracer act = do
292withRegisteredTracer act = do
269 currentTracer <- whereis "tracer"
293 currentTracer <- whereis "tracer"
270 case currentTracer of
294 case currentTracer of
@@ -301,6 +325,12 @@ disableTrace :: Process ()
301disableTrace =
325disableTrace =
302 withLocalTracerSync $ \t sp -> Tracer.disableTraceSync t sp
326 withLocalTracerSync $ \t sp -> Tracer.disableTraceSync t sp
328+getTraceFlags :: Process TraceFlags
331+ withLocalTracer $ \t -> liftIO $ Tracer.getTraceFlags t sp
304-- | Set the given flags for the current tracer.
334-- | Set the given flags for the current tracer.
305setTraceFlagsAsync :: TraceFlags -> Process ()
335setTraceFlagsAsync :: TraceFlags -> Process ()
306setTraceFlagsAsync f = withLocalTracer $ \t -> liftIO $ Tracer.setTraceFlags t f
336setTraceFlagsAsync f = withLocalTracer $ \t -> liftIO $ Tracer.setTraceFlags t f