
#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