Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Oct 2003 22:06:10 -0400 (EDT)
From:      Daniel Eischen <eischen@vigrid.com>
To:        Alexey Zelkin <phantom@freebsd.org>
Cc:        threads@freebsd.org
Subject:   Re: libc_r & direct usage of syscalls
Message-ID:  <Pine.GSO.4.10.10310222155520.29526-100000@pcnet5.pcnet.com>
In-Reply-To: <20031023010038.A71141@phantom.cris.net>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.10.10310222155520.29526-100000>