Profiling option -hb is not thread safe
This ticket is a continuation of #11978 (closed) and #12009 (closed). After fixing a couple of issues in those two tickets I found that the profiling run time is not thread safe.
Have a trivial test program (written as one of the tests for #11978 (closed)):
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Exception
import Control.Monad
main :: IO ()
main = do
putStrLn "Start ..."
mvar <- newMVar (0 :: Int)
let count = 50
forM_ [ 1 .. count ] $ const $ forkIO $ do
threadDelay 100
i <- takeMVar mvar
putMVar mvar $! i + 1
threadDelay 1000000
end <- takeMVar mvar
putStrLn $ "Final result " ++ show end
assert (end == count) $ return ()
Compiling that with a compiler that has bug fixes arising from #11978 (closed) and #12009 (closed) as:
inplace/bin/ghc-stage2 testsuite/tests/profiling/should_run/T11978b.hs \
-fforce-recomp -rtsopts -fno-warn-tabs -O -prof -static -auto-all \
-threaded -debug -o T11978b
and run as:
./T11978b +RTS -p -hb -N10
crashes in a number of different ways. I've seen at least 3 different assertion failures and numerous segfaults (in different stg_ap_*
functions).
Replace -hb
with other profiling options like -hr
etc do not seem to crash.
Looking at code, one example of lack of thread safetly is the function LDV_recordDead
which mutates global variable censuses
which does not have any locking around it. Only figured this out because the following assert (in LDV_recordDead
) was being triggered occasionally.
ASSERT(censuses[t].void_total < censuses[t].not_used);