Too many nested forkProcess's eventually cause SIGSEGV in the child
Original Haskell-cafe thread: https://groups.google.com/forum/#!msg/haskell-cafe/kHMsYRMcdPs/vWD9T7saCAAJ
Here is a slightly modified test program from that thread:
-- 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.
Trac metadata
Trac field | Value |
---|---|
Version | |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Runtime System |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | simonmar |
Operating system | |
Architecture |