libc_r & direct usage of syscalls
Daniel Eischen
eischen at vigrid.com
Wed Oct 22 19:06:13 PDT 2003
On Thu, 23 Oct 2003, Alexey Zelkin wrote:
> hi,
>
> Some of you may remember a story about strange problems I had
> with native jdk14 and fork() calls.
>
> In few words -- sometimes, in absolutely random order JVM just after
> call to fork() function become unusable due to SIGBUS signal storm
> (JVM signal handler decided that this signal is not fatal and did not
> stop an application).
>
> Today I have completely tracked it down. Or correctly to say
> got a 100% reproducible .java testcase and wrote few more .c testcases in
> order to prove my point of view.
>
> JVM is using internally usual stack protection logic. Every two pages on
> borders of stack are protected with mmap(). When something accesses
> it SIGBUS is generated and signal handler forces overflowing thread
> to rollback some operation until it may safely continue its job.
>
> fork() is special case here. When fork() is called, child process
> is need to reinitialize a libc_r internal state (this job is done by
> fork() wrapper located in libc_r/uthread/uthread_fork.c). One of steps
> of reinitialization process is free()'ing of pthreads stacks. Caveat here
> is unchanged protections on stack pages. Right after some stacks are
> free()'ed, malloc internal (struct pginfo *) info got allocated into
> protected region and this info being changed we get a big *KABOOM* (i.e.
> SIGBUS).
Here's what POSIX has to say about fork() and threaded processes:
A process shall be created with a single thread. If a multi-threaded
process calls fork(), the new process shall contain a replica of the
calling thread and its entire address space, possibly including the
states of mutexes and other resources. Consequently, to avoid
errors, the child process may only execute async-signal-safe
operations until such time as one of the exec functions is called.
[THR] Fork handlers may be established by means of the
pthread_atfork() function in order to maintain application
invariants across fork() calls.
When the application calls fork() from a signal handler and any of
the fork handlers registered by pthread_atfork() calls a function
that is not asynch-signal-safe, the behavior is undefined.
Libkse currently doesn't do any reinitialization of internal library
state (libc _or_ libkse) on a fork(). You cannot rely on libc
state (malloc state, e.g.) or libkse state after a fork().
For what purpose is fork() being used by the JVM?
--
Dan Eischen
More information about the freebsd-threads
mailing list