Subject: Re: 32 bit linux java
To: Christos Zoulas <christos@astron.com>
From: Arto Huusko <arto.huusko@pp2.inet.fi>
List: port-amd64
Date: 11/24/2007 13:21:03
This is a multi-part message in MIME format.
--------------070009040302030203080102
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Christos Zoulas wrote:

>> As the line numbers say it moves save_ucontext call a few
>> lines up, to happen before sendsig_reset, not afer. The
>> whitespace is artifact of the mailer I think.
> 
> Can you please send both patches with diff -u please?

Attached.


There is another problem with signals in threads linux emulation that
also affects plain linux emul, not only linux32. The threads are really
cloned processes, that share a lot of state, including signal actions.
However, the p_sigctx structure in the process structure is not shared.

I'm not sure if this structure is even supposed to be shared, because
it has to do with per process signal handling state, but the ps_sigcatch
sigset is tied to signal actions:

  - in sys_sig.c, sigaction1() adds or removes signal from ps_sigcatch
    set, depending on whether the signal has default action or not.

  - in kern_sig.c, trapsignal() checks ps_sigcatch to determine what to
    do with the signal

Because ps_sigcatch is not shared, and not even inherited from parent
to child when cloning with KERN_SHARESIGS, java fails like this:

  - one of the java processes installs a signal handler

  - the java process clones itself (creates a new thread)

  - the child process receives a signal, for example SIGSEGV

  -> kernel sees that the child process does not have the signal
     in ps_sigcatch

  -> kernel delivers sig with kpsignal2()

  -> kpsignal2 delivers the sig with SIG_DLF handler (I didn't
     check why)

I tried to help this by patching linux32 fork hook to make child process
inherit p_sigctx from parent. This however does not help the matters,
because what actually can, and does happen is this:

  - first java process X starts

  - java clones a new thread Y

  - thread Y installs signal actions

  - thread X clones a new thread Z

  - thread Z receives a signal

So even inheriting does not help, because it is not the root process
that installs the signal handler.


Should I open a PR. It seems this latest signal issue is a bit more
complicated to fix.

BTW, where is p_sigctx initialized/inherited during fork. At least
ps_sigcode looks like a field that should be inherited always?

--------------070009040302030203080102
Content-Type: text/plain;
 name="linux_exec_patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="linux_exec_patch"

Index: linux32_exec.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux32/common/linux32_exec.c,v
retrieving revision 1.7
diff -u -r1.7 linux32_exec.c
--- linux32_exec.c	19 Oct 2007 12:16:39 -0000	1.7
+++ linux32_exec.c	24 Nov 2007 11:03:04 -0000
@@ -108,7 +108,7 @@
 	linux32_sysent,
 	linux32_syscallnames,
 	linux32_sendsig,
-	trapsignal,
+	linux_trapsignal,
 	NULL,
 	linux32_sigcode,
 	linux32_esigcode,

--------------070009040302030203080102
Content-Type: text/plain;
 name="linux_machdep_patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="linux_machdep_patch"

Index: linux32_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux32/arch/amd64/linux32_machdep.c,v
retrieving revision 1.12
diff -u -r1.12 linux32_machdep.c
--- linux32_machdep.c	19 Oct 2007 12:16:39 -0000	1.12
+++ linux32_machdep.c	24 Nov 2007 11:02:00 -0000
@@ -246,9 +246,9 @@
 	}
 
 	/* Save register context. */
+	linux32_save_ucontext(l, tf, mask, sas, &frame.sf_uc);
 	sendsig_reset(l, sig);
 	mutex_exit(&p->p_smutex);
-	linux32_save_ucontext(l, tf, mask, sas, &frame.sf_uc);
 	error = copyout(&frame, fp, sizeof(frame));
 	mutex_enter(&p->p_smutex);


--------------070009040302030203080102--