Why doesn't Visual Studio catch fatal exception in JNI callbacks?

S

Steve

I'm working in Visual Studio 2008 on Windows XP. I've got a 32-bit
environment at work and a 64-bit environment at home, and both exhibit
this mystery.

I'm working on a project that consists of a C++ main program with an
embedded JVM. The C++ code calls java bytecode via JNI and that
bytecode can call back into the C++ code via JNI native methods.

This all works great...except when it doesn't. I'm finding it very
difficult to debug problems in my native callback methods because
whenever a fatal exception (say a null pointer reference, for example)
occurs, the program just exits rather than dropping into the debugger
like I would expect.

To be clear...I'm running my C++ app in the debugger. I can step
around, and if I dereference a null pointer, I get the familiar
"something bad happened, do you want to debug?" dialog. But if my
code enters the JVM and then calls back into my C++ code via a JNI
native method, a null pointer deref leads to my app just exiting
without me getting any kind of look at what caused the exit.

Can anyone tell me why this occurs? Better still, is there some way I
can change this behavior so that fatal problems in native methods are
caught by the Visual Studio debugger?

TIA for any help, which will be greatly appreciated.

Steve
 
R

Roedy Green

TIA for any help, which will be greatly appreciated.

One technique is to try to test the C++ and Java portions separately
by writing test drivers in the same language. When you have the code
working solidly, then glue them together with the JNI.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"Patriotism is fierce as a fever, pitiless as the grave, blind as a stone, and as irrational as a headless hen."
~ Ambrose Bierce (born: 1842-06-24 died: 1914 at age: 71)
 
T

Tom Anderson

I'm working in Visual Studio 2008 on Windows XP. I've got a 32-bit
environment at work and a 64-bit environment at home, and both exhibit
this mystery.

I'm working on a project that consists of a C++ main program with an
embedded JVM. The C++ code calls java bytecode via JNI and that
bytecode can call back into the C++ code via JNI native methods.

This all works great...except when it doesn't. I'm finding it very
difficult to debug problems in my native callback methods because
whenever a fatal exception (say a null pointer reference, for example)
occurs, the program just exits rather than dropping into the debugger
like I would expect.

To be clear...I'm running my C++ app in the debugger. I can step
around, and if I dereference a null pointer, I get the familiar
"something bad happened, do you want to debug?" dialog. But if my
code enters the JVM and then calls back into my C++ code via a JNI
native method, a null pointer deref leads to my app just exiting
without me getting any kind of look at what caused the exit.

Can anyone tell me why this occurs? Better still, is there some way I
can change this behavior so that fatal problems in native methods are
caught by the Visual Studio debugger?

Pure speculation follows.

My guess would be that it's to do with signal handling, or whatever
Windows's equivalent of that is. When a thread does something illegal, it
is suspended, and a signal is delivered to the owning process. In a normal
app, the handler for this would usually terminate the app, or at least the
thread. In an app running under the debugger, the debugger installs its
own signal handler which triggers debugging instead. But i suspect the JVM
also installs its own handler, so that it can manage errors its way, by
throwing Errors in java or whatever or whatever. It will install that
handler when you call into it, and it remove it before it returns.

However, if java makes a callback into C, then that still happens with the
JVM's signal handler in place, and so the JVM does the handling, rather
than the debugger - and in this case, it just exits (which surprises me a
little, but is believable).

As for solutions, you need to get the debugger to put its signal handler
in place again on reentry into C. I have no idea how you'd do that.

The best i can suggest for forward progress would be some informed
googling or asking on stackoverflow.com!

tom
 
S

Steve

Thanks guys for your help. I did some googling and found this, which
seems to explain pretty well what the JVM is doing:

http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/signals.html

Section 6.2 explains the exception handlers (the equivalent of Unix
signals for Windows) that the JVM installs, and also explains how to
insert your own handlers in the chain. I still don't see how to get
the behavior I really want, which is to not have ANY exception
handlers, but this should give me a solution by letting me catch
exceptions in my own code while I still have a stack trace to see what
went wrong.

This link is a hot find in general...a Java troubleshooting guide from
Sun...isn't that special.

Be well all!

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top