[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