#1391: forkProcess() in Schedule.c with -threaded should initialize mutexes in
child process (POSIX)
----------------------------------+-----------------------------------------
  Reporter:  thorkilnaur          |          Owner:         
      Type:  bug                  |         Status:  new    
  Priority:  normal               |      Milestone:         
 Component:  Runtime System       |        Version:  6.7    
  Severity:  normal               |       Keywords:         
Difficulty:  Unknown              |             Os:  MacOS X
  Testcase:  forkprocess01(ghci)  |   Architecture:  powerpc
----------------------------------+-----------------------------------------
{{{forkProcess()}}} in {{{Schedule.c}}} implements
 {{{System.Posix.Process.forkProcess}}} essentially by {{{fork()}}}'ing. In
 http://www.gnu.org/software/libc/manual/html_node/Threads-and-Fork.html we
 read that

   It's not intuitively obvious what should happen when a multi-threaded
 POSIX process calls fork. ...
   fork duplicates the whole memory space, including mutexes in their
 current locking state, but
   only the calling thread: other threads are not running in the child
 process. The mutexes are
   not usable after the fork and must be initialized with
 pthread_mutex_init in the child process.

 Although a lot of things happen in {{{forkProcess()}}} in {{{Schedule.c}}}
 in the child process after {{{fork()}}} returns, this initialization of
 mutexes and related delicate matters are not done.

 On my PPC Mac OS X 10.4.9, I have observed this to eventually result in
 the child process getting a {{{SIGSEGV}}} (signal 11; segmentation fault)
 when run via {{{ghc --interactive}}}. The failing test case
 {{{forkprocess01(ghci)}}} for PPC Mac OS X is an example of this.

 The case of {{{forkprocess01}}} failing when run via {{{ghci
 --interactive}}} comes about because ghc itself is linked with
 {{{-threaded}}}. With a ghc linked without {{{-threaded}}}, the
 segmentation fault does not happen.

 When executing {{{forkprocess01}}} compiled with {{{--make}}}
 {{{-threaded}}}, the error again cannot be reproduced. But this seems to
 be because {{{forkprocess01}}} itself does not use multiple threads. With
 a slightly extended version of {{{forkprocess01}}} called
 {{{forkprocess03}}}:
 {{{
 -- forkprocess03.hs:
 -- Test that we can call exitFailure in a forked process, and have it
 -- communicated properly to the parent.
 -- Do this (forkprocess01) within a forkIO'ed child process.
 import System.Exit
 import System.Posix.Process
 import Control.Concurrent
 main0 = do
   p <- forkProcess $ exitWith (ExitFailure 72)
   r <- getProcessStatus True False p
   print r
 main = do
   p <- forkIO $ main0
   threadDelay 10000000
   print p
 }}}
 the erroneous reaction can be observed when compiled with {{{-threaded}}}
 using a fairly recent ghc HEAD:
 {{{
 $ /Users/thorkilnaur/tn/GHCDarcsRepository/ghc-HEAD-for-HughesPJ-wrong-
 fill-indent-20070506_1304/ghc/compiler/stage2/ghc-inplace --version
 The Glorious Glasgow Haskell Compilation System, version 6.7.20070513
 $ touch forkprocess03.hs
 $ /Users/thorkilnaur/tn/GHCDarcsRepository/ghc-HEAD-for-HughesPJ-wrong-
 fill-indent-20070506_1304/ghc/compiler/stage2/ghc-inplace --make
 forkprocess03 -threaded
 [1 of 1] Compiling Main             ( forkprocess03.hs, forkprocess03.o )
 Linking forkprocess03 ...
 $ ./forkprocess03
 Just (Terminated 11)
 ThreadId 4
 $
 }}}
 Whereas without {{{-threaded}}}, the program seems to run fine:
 {{{
 $ touch forkprocess03.hs
 $ /Users/thorkilnaur/tn/GHCDarcsRepository/ghc-HEAD-for-HughesPJ-wrong-
 fill-indent-20070506_1304/ghc/compiler/stage2/ghc-inplace --make
 forkprocess03
 [1 of 1] Compiling Main             ( forkprocess03.hs, forkprocess03.o )
 Linking forkprocess03 ...
 $ ./forkprocess03
 Just (Exited (ExitFailure 72))
 ThreadId 2
 $
 }}}
 The repair, however, is not particularly obvious. The above reference
 suggests using {{{pthread_atfork}}} to set up handlers to lock all mutexes
 before {{{fork()}}}'ing and subsequently unlock them in the parent and
 initializing them in the child. But even if this is chosen as the way
 forward, additional matters need to be clarified, to ensure that such
 handling plays well with the rest of the threaded runtime system and also
 retains the Windows variant of things. Also, if anything is done about
 this, #1185 should probably considered as well.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1391>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to