{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} {-| 'B.ByteString' variant of the tracing functions in "Debug.Trace". -} module Debug.Trace.ByteString ( traceEvent , traceEventIO , traceMarker , traceMarkerIO , unsafeTraceEvent , unsafeTraceEventIO , unsafeTraceMarker , unsafeTraceMarkerIO ) where import Control.Monad (when) import GHC.Exts (Ptr(..), traceEvent#, traceMarker#) import GHC.IO (IO(..)) import qualified GHC.RTS.Flags as Flags import qualified System.IO.Unsafe as Unsafe import qualified Data.ByteString as B import qualified Data.ByteString.Unsafe as BU import Debug.Trace.Flags (userTracingEnabled) -- | 'B.ByteString' variant of 'Debug.Trace.traceEvent'. -- -- \(O(n)\) This function copies the 'B.ByteString' to convert it to a -- null-terminated 'Foreign.C.Types.CString'. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. traceEvent :: B.ByteString -> a -> a traceEvent message a | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do traceEventIO message return a | otherwise = a {-# NOINLINE traceEvent #-} -- | 'B.ByteString' variant of 'Debug.Trace.traceEventIO'. -- -- \(O(n)\) This function copies the 'B.ByteString' to convert it to a -- null-terminated 'Foreign.C.Types.CString'. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. traceEventIO :: B.ByteString -> IO () traceEventIO message = when userTracingEnabled $ B.useAsCString message $ \(Ptr p) -> IO $ \s -> case traceEvent# p s of s' -> (# s', () #) -- | 'B.ByteString' variant of 'Debug.Trace.traceMarker'. -- -- \(O(n)\) This function copies the 'B.ByteString' to convert it to a -- null-terminated 'Foreign.C.Types.CString'. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. traceMarker :: B.ByteString -> a -> a traceMarker message a | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do traceMarkerIO message return a | otherwise = a {-# NOINLINE traceMarker #-} -- | 'B.ByteString' variant of 'Debug.Trace.traceMarkerIO'. -- -- \(O(n)\) This function copies the 'B.ByteString' to convert it to a -- null-terminated 'Foreign.C.Types.CString'. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. traceMarkerIO :: B.ByteString -> IO () traceMarkerIO message = when userTracingEnabled $ B.useAsCString message $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) -- | 'B.ByteString' variant of 'Debug.Trace.traceEvent'. -- -- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input -- string to be null-terminated. It is user's responsibility to null-terminate -- the input. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. unsafeTraceEvent :: B.ByteString -> a -> a unsafeTraceEvent message a | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do unsafeTraceEventIO message return a | otherwise = a {-# NOINLINE unsafeTraceEvent #-} -- | 'B.ByteString' variant of 'Debug.Trace.traceEventIO'. -- -- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input -- string to be null-terminated. It is user's responsibility to null-terminate -- the input. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. unsafeTraceEventIO :: B.ByteString -> IO () unsafeTraceEventIO message = when userTracingEnabled $ BU.unsafeUseAsCString message $ \(Ptr p) -> IO $ \s -> case traceEvent# p s of s' -> (# s', () #) -- | 'B.ByteString' variant of 'Debug.Trace.traceMarker'. -- -- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input -- string to be null-terminated. It is user's responsibility to null-terminate -- the input. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. unsafeTraceMarker :: B.ByteString -> a -> a unsafeTraceMarker message a | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do unsafeTraceEventIO message return a | otherwise = a {-# NOINLINE unsafeTraceMarker #-} -- | 'B.ByteString' variant of 'Debug.Trace.traceMarkerIO'. -- -- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input -- string to be null-terminated. It is user's responsibility to null-terminate -- the input. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. unsafeTraceMarkerIO :: B.ByteString -> IO () unsafeTraceMarkerIO message = when userTracingEnabled $ BU.unsafeUseAsCString message $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #)