[GHC] #12436: Too many nested forkProcess's eventually cause SIGSEGV in the child

GHC ghc-devs at haskell.org
Tue Jul 26 13:41:41 UTC 2016


#12436: Too many nested forkProcess's eventually cause SIGSEGV in the child
-------------------------------------+-------------------------------------
           Reporter:  tolik          |             Owner:
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:
          Component:  Runtime        |           Version:
  System                             |
           Keywords:  forkProcess,   |  Operating System:  Linux
  SIGSEGV                            |
       Architecture:  x86_64         |   Type of failure:  Runtime crash
  (amd64)                            |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 Original Haskell-cafe thread: https://groups.google.com/forum/#!msg
 /haskell-cafe/kHMsYRMcdPs/vWD9T7saCAAJ

 Here is a slightly modified test program from that thread:
 {{{#!hs
 -- fork-bug.hs
 import System.Environment (getArgs)
 import System.Posix.Process (forkProcess)

 fork_ 0 = putStrLn "Done forking"
 fork_ n = forkProcess (fork_ (n - 1)) >> return ()

 main = do
     [n] <- getArgs
     fork_ (read n)
 }}}

 With n big enough the program doesn't print anything and crashes with
 SIGSEGV at (semi-)random places (the crash is somewhat hard to demonstrate
 from the shell):
 {{{
 $ ./fork-bug 100; sleep 0.1
 Done forking
 $ ./fork-bug 500; sleep 0.1
 Done forking
 $ ./fork-bug 1000; sleep 0.1
 $
 }}}

 Looks like the problem lies in C-stack exhaustion in children - lowering
 the stack limit makes the crash happen much earlier:
 {{{
 $ (ulimit -s 128; ./fork-bug 5; sleep 0.1)
 Done forking
 $ (ulimit -s 128; ./fork-bug 6; sleep 0.1)
 Done forking
 $ (ulimit -s 128; ./fork-bug 7; sleep 0.1)
 $ (ulimit -s 128; ./fork-bug 8; sleep 0.1)
 $
 }}}

 Tracing with gdb shows that with each forkProcess the stack in the forked
 child goes deeper and deeper, although gdb shows call stacks of constant
 depth:
 {{{
 $ gdb -q fork-bug
 Reading symbols from fork-bug...(no debugging symbols found)...done.
 (gdb) set follow-fork-mode child
 (gdb) break forkProcess
 Breakpoint 1 at 0x470a60
 (gdb) display $rsp
 (gdb) run 3
 Starting program: /tmp/fork-bug 3
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

 Breakpoint 1, 0x0000000000470a60 in forkProcess ()
 1: $rsp = (void *) 0x7fffffff9e28
 (gdb) bt
 #0  0x0000000000470a60 in forkProcess ()
 #1  0x0000000000406215 in s3sP_info ()
 #2  0x0000000000000000 in ?? ()
 (gdb) continue
 Continuing.
 [New process 20434]
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
 [Switching to Thread 0x7ffff7fd5740 (LWP 20434)]

 Breakpoint 1, 0x0000000000470a60 in forkProcess ()
 1: $rsp = (void *) 0x7fffffff5d08
 (gdb) bt
 #0  0x0000000000470a60 in forkProcess ()
 #1  0x0000000000406215 in s3sP_info ()
 #2  0x0000000000000000 in ?? ()
 (gdb) continue
 Continuing.
 [New process 20435]
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
 [Switching to Thread 0x7ffff7fd5740 (LWP 20435)]

 Breakpoint 1, 0x0000000000470a60 in forkProcess ()
 1: $rsp = (void *) 0x7fffffff1be8
 (gdb) bt
 #0  0x0000000000470a60 in forkProcess ()
 #1  0x0000000000406215 in s3sP_info ()
 #2  0x0000000000000000 in ?? ()
 (gdb) continue
 Continuing.
 [New process 20436]
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
 Done forking
 [Inferior 4 (process 20436) exited normally]
 }}}

 These results are from Ubuntu 14.04.4 with GHC 7.6.3, although OP reported
 using 7.10.3 and HEAD.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12436>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list