From owner-freebsd-threads@FreeBSD.ORG Wed Oct 22 19:06:12 2003 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E5CAB16A4B3; Wed, 22 Oct 2003 19:06:12 -0700 (PDT) Received: from mail.pcnet.com (mail.pcnet.com [204.213.232.4]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7257B43FB1; Wed, 22 Oct 2003 19:06:11 -0700 (PDT) (envelope-from eischen@vigrid.com) Received: from mail.pcnet.com (mail.pcnet.com [204.213.232.4]) by mail.pcnet.com (8.12.10/8.12.1) with ESMTP id h9N26ABR001393; Wed, 22 Oct 2003 22:06:10 -0400 (EDT) Date: Wed, 22 Oct 2003 22:06:10 -0400 (EDT) From: Daniel Eischen X-Sender: eischen@pcnet5.pcnet.com To: Alexey Zelkin In-Reply-To: <20031023010038.A71141@phantom.cris.net> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: threads@freebsd.org Subject: Re: libc_r & direct usage of syscalls X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Oct 2003 02:06:13 -0000 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