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>