libc_r & direct usage of syscalls
Alexey Zelkin
phantom at FreeBSD.org.ua
Thu Oct 23 02:35:04 PDT 2003
hi,
On Wed, Oct 22, 2003 at 10:06:10PM -0400, Daniel Eischen wrote:
> > 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.
>From quick look I was unable to find any entity named pthread_atfork()
in FreeBSD. I also doubt it will help with my issue at all, because
most probabaly atfork functions will be executed at the end of pthread_fork(),
but my problem appears at the begining of the function.
> 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().
Well. I looked on fork() implementation in libkse and it looks safe for
my case. Is there any standard way to detect which library I am running ?
I can do runtime check (using dl*() funcs) in order to understand which
library application running and execute different code paths.
> For what purpose is fork() being used by the JVM?
For spawning another process. As I shown in code examples in previous letter
fork() is used to born another process, then close unused file descriptors
in child and then call execvp().
More information about the freebsd-threads
mailing list