This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: Question about POSIX libgcj signals / exception handling
- From: David Daney <ddaney at avtrex dot com>
- To: gnustuff at thisiscool dot com
- Cc: java at gcc dot gnu dot org
- Date: Fri, 10 Mar 2006 22:08:26 -0800
- Subject: Re: Question about POSIX libgcj signals / exception handling
- References: <URC8D9GFKFBA0KF94DBGOWT3YDCIC.441257fc@d9300>
Mohan Embar wrote:
Hi All,
I could dig into the code for this, but I was
wondering if anyone know the answer off the
top of their head.
Are the signal handlers in POSIX libgcj set up
such that the application is bulletproof and
immune from core dumps?
Certainly. With java and especially libgcj it is impossible to write
buggy code. I have not had a single bug in over three years!
Even if I do native stuff where
I divide by zero or dereference invalid pointers?
I'm not overly experienced with POSIX signal handling
and was wondering if a try...catch block in my main()
method was sufficient enough to catch all mishaps,
even native ones. Also, are there any restrictions
or caveats concerning what I can do when reacting to
exceptions triggered by such signals (as opposed to
"normal" Java exceptions)? I seem to recall from the
little UNIX programming I've done that you shouldn't
do too much in a signal handler.
Reading this:
http://gcc.gnu.org/java/port-signals.html
That is a little out of date. i386 MAKE_THROW_FRAME is a nop. Stack
unwinding through the signal frame is handled by the DWARF based
exception unwinder in libgcc.
It appears that everything is handled properly in the
POSIX implementation, but I wanted to make sure.
These questions apply to both Linux c86 and OS X
PPC implementations.
For x86-linux:
SIGSEGV gets converted to NullPointerException. This is unconditional
it happens even if the faulting location is far away from address zero.
Native code is not treated any differently than the java code.
Any SIGSEGV is converted to NPE.
SIGFPE likewise is converted to ArithmaticException, but on the x86 some
analysis of the faulting code is done first as x86 sometimes generates
the SIGFPE when the JLS requires it not to throw the exception. In this
case things are fixed up and control returned to the faulting code.
The GC uses two signals that are not related to machine faults. The
Thread.Interrupt facility also uses a signal (I forget which ones),
java.lang.Process uses SIGCHLD.
SIGBUS and SIGILL are not handled by libgcj. If you get one of them,
your program will be terminated unless you explicitly install your own
handler for them. But they usually indicate that something is seriously
screwed up, so bailing out is probably for the best.
Likewise SIGABRT (used by some C asserts and abort() is not handled).
In OS X I don't know, but it is probably similar.
Each OS/architecture combination needs a bit of tricky code
(MD_FALLBACK_?????? or something, I should remember its name as I wrote
one once) to convert the signals to java exceptions. If that code is
not present, gcj falls back to generating explicit checks for all these
things.
One thing that you need to remember if you are using native code is to
have GCC generate exception data for all your non-java code so that
faults in native code can be gracefully handled.
David Daney