Debugging JNI-based applications on Windows

One of the most annoying things about developing Qt Jambi has so far been the Java Virtual Machine's tendency to intercept exceptions in the native code, thus disabling any mechanism installed in the OS serving to handle these. Instead of your application crashing violently, it outputs a message to the console apologizing intently that such an awful thing would ever occur, and it also dumps a helpful .log file to the disk, containing stack traces and environment details that can be helpful in debugging the problem.

The problem is, however, that Windows users of tools such as Visual Studio are used to having a debugger registered with the operating system, so that, in cases where an application crashes, they can simply hit the "Debug" button in the default dialog that pops up, attach to the process, and jump directly into the source code at the exact location where the problem occurred. There are no limits to how useful this mechanism is, and I suspect it literally saves me hours of work every week.

When writing JNI-based applications that run on top of the virtual machine, however, this is simply not supported. Apparently, Sun made an attempt to fix this themselves, but there were some problems in the integration process [edit: The URL seems to have gone dead. Here's a cached version.]

Having complained about the problem for much too long, I finally had some extra time last week, and decided to fix the problem myself. I set out to patch the JVM. My goals were: 1. Keep the current logging facility. 2. Get back the default exception handler. 3. Do as little work as possible.

Since you're supposed to have screen shots in these blog-things, here's how it looks when it's done:


Patching and building the JVM is suprisingly simple. The code is well-organized, and the build system is as good as fool proof. So kudos to the developers for that :-)

My patch is by no means elegant. In fact, it's downright stupid. I also make no guarantee that it won't break earth or anything. However, I thought there might be other people out there who would like to do this, so here it is in case you're interested:

--- srcsharevmutilitiesvmError.cpp-backup 2007-02-16 15:39:41.760875000 +0100
+++ srcsharevmutilitiesvmError.cpp 2007-02-16 16:01:57.104625000 +0100
@@ -664,10 +664,11 @@
} else {
if (recursive_error_count++ > 30) {
out.print_raw_cr("[Too many errors, abort]");
- os::die();
+ //os::die();
+ return ;

- jio_snprintf(buffer, sizeof(buffer),
+ /*jio_snprintf(buffer, sizeof(buffer),
"[error occurred during error reporting, step %d, id 0x%x]",
first_error ? first_error->_current_step : -1,
@@ -679,7 +680,7 @@;
- }
+ }*/

@@ -791,11 +792,11 @@
static bool skip_os_abort = false;
if (!skip_os_abort) {
skip_os_abort = true;
- os::abort();
+ //os::abort();

// if os::abort() doesn't abort, try os::die();
- os::die();
+ //os::die();

Blog Topics: