This is the mail archive of the
mailing list for the GCC project.
Re: [PATCH] Fix libjava breakage with glibc 2.2.2pre
- To: Bryce McKinlay <bryce at albatross dot co dot nz>
- Subject: Re: [PATCH] Fix libjava breakage with glibc 2.2.2pre
- From: Andrew Haley <aph at redhat dot com>
- Date: Wed, 14 Feb 2001 12:34:25 +0000 (GMT)
- Cc: jakub at redhat dot com, gcc-patches at gcc dot gnu dot org
- References: <3A8A716D.847170FB@albatross.co.nz>
Bryce, thanks for CC:ing me with this. My mail filter broke so I
didn't see the original message.
Bryce McKinlay writes:
> Jakub writes:
> > __sigaction() is no longer declared in glibc headers (it is internal, so why
> > should it). This patch makes libjava compile with current glibc.
> > Ok to commit (for branch as well)?
No: it will break libgcj, and the test file Divide_1.java will reveal
> > 2001-02-14 Jakub Jelinek
> > * include/i386-signal.h (INIT_SEGV, INIT_FPE): Use sigaction instead
> > of __sigaction or syscall (SYS_sigaction).
> > * include/ppc-signal.h (INIT_SEGV, INIT_FPE): Likewise.
> If __sigaction() is no longer available then we probibly need to use
> syscall (SYS_sigaction), for INIT_FPE at least. The reason is that
> libjava needs to modify the signal context (so it can conditionally
> throw exceptions from the sig handlers), and glibc/linuxthreads fails to
> copy the modified sigcontext back to the kernel.
> This code is a constant source of trouble but quite neccessary,
> unless anyone has better ideas for how to implement the SIGFPE ->
> ArithmeticException mapping.
> btw, did you read this comment in i386-signal.h (right below the code
> you changed)?
> /* You might wonder why we use syscall(SYS_sigaction) in INIT_FPE
> * instead of the standard sigaction(). This is necessary because of
> * the shenanigans above where we increment the PC saved in the
> * context and then return. This trick will only work when we are
> * called _directly_ by the kernel, because linuxthreads wraps signal
> * handlers and its wrappers do not copy the sigcontext struct back
> * when returning from a signal handler. If we return from our divide
> * handler to a linuxthreads wrapper, we will lose the PC adjustment
> * we made and return to the faulting instruction again. Using
> * syscall(SYS_sigaction) causes our handler to be called directly by
> * the kernel, bypassing any wrappers. This is a kludge, and a future
> * version of this handler will do something better. */
> Andrew Haley may have more to say about this issue. I'm not sure what
> "something better" might be ;-)
There is a couple of possibilities I can think of: either use the
divide subroutine or our own handler can unwind the stack and return.
The former is undoubtedly the most reliable and portable, and the
latter is the most efficient. The latter has its own problems,
though: the interface to the Linux sigcontext has changed over the
last year or two and a backwards compatible version may be difficult
to get right.
The current version will break if one day the Linux kernel decides not
to copy the saved registers back whan returning.