Debugging crashes in JNI code on windows

If you run into an access violation in your native code called from java you normally get a hs_err_pid<pid>.log file that may or may contain a usable stack trace. This text is about how to do better than that: launch a debugger (or create a real crash dump) at the point of the crash.The (sun) jvm installs an exception filter. The jvm also uses/handles structured exceptions internally: there are a lot of first-chance exceptions that are part of the normal running of the jvm and you are not interested in. You don’t want to break on all first-chance exceptions (as, e.g., gdb would by default do).

Hence, you need to let the jvm notice that this is not the kind of exception it can handle, but is a real problem.

A windows process can pass on an exception it can’t handle. This is called a second-chance exception and it can be handed over to a debugger.

If you use -XX:OnError or -XX:+ShowMessageBoxOnError the jvm _doesn’t_ generate a second-chance exception. You can use these options to attach a debugger or to generate a core dump, but the exception and its context are gone.

The only option (AFAICT) that doesn’t lose the exception context is -XX:+UseOSErrorReporting. This lets the second-chance exception bubble up to normal windows error handling: Windows Error Reporting (http://support.microsoft.com/kb/310414) and/or Just-in-time debugging (http://support.microsoft.com/kb/103861) (and generates a hs_err<pid>.log file).

For the debugger you can use windbg (free-as-in-beer, from Windows Debugging Tools, now distributed as a part of the Platform SDK) or Visual Studio (the non-free version, Express editions cannot be used for just-in-time debugging), or some other debugger like OllyDbg or watcom debugger.

You need to choose a debugger that supports the symbol information for your executables. This pretty much means that if you want to compile with gcc you need to use gdb or drmingw (the normal gcc debug information formats, stabs and DWARF2 are not supported by microsoft debuggers, and although some people claim that the COFF symbol table produced by ‘gcc -gcoff’ can be read by windbg I’ve never been able to make that work) – if you want to use Microsoft’s debuggers you need to build with Microsoft compilers (from Visual Studio or Platform SDK (or WinDDK)) or something else that creates windows symbols, like Intel compilers.

BTW1, the jvm won’t read symbols from gcc-compiled code either, so if you want symbols in the hs_err_pid<pid>.log files, you need to compile with something that produces windows-like symbols.

BTW2, if you launch a process under cygwin, it doesn’t use the platform just-in-time debugging configuration and hence -XX:+UseOSErrorReporting doesn’t work either. You can fix this by calling ::SetErrorMode(0) somewhere. See https://bugs.webkit.org/show_bug.cgi?id=55222

BTW3, this is all on the (currently latest) JDK 6u27. The release notes claim there were improvements to exception handling in native code.

This entry was posted in Uncategorized. Bookmark the permalink.

Comments are closed.