[GHC] #12019: Profiling option -hb is not thread safe
GHC
ghc-devs at haskell.org
Mon Sep 5 21:50:00 UTC 2016
#12019: Profiling option -hb is not thread safe
-------------------------------------+-------------------------------------
Reporter: erikd | Owner: erikd
Type: bug | Status: patch
Priority: normal | Milestone: 8.0.2
Component: Runtime System | Version: 8.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: Runtime crash | Test Case:
Blocked By: | Blocking:
Related Tickets: #11978, #12009 | Differential Rev(s): Phab:D2516
Wiki Page: |
-------------------------------------+-------------------------------------
Changes (by bgamari):
* status: new => patch
* differential: => Phab:D2516
@@ -7,1 +7,1 @@
- {{{
+ {{{#!hs
New description:
This ticket is a continuation of #11978 and #12009. 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):
{{{#!hs
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 and
#12009 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);
}}}
--
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12019#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list