4

I'm developing a C++ program (Win32, MS Visual Studio 2008) which creates a Java VM via JNI as outlined here. It has been working fine for a long time, with both Java 6 and Java 7.

Today I have installed a new version of JRE; something went wrong in the installer, and the JRE become corrupt. I noticed that my C++ program doesn't start and doesn't issue any warning messages. Debugging the program showed that it runs successfully until the JNI_CreateJavaVM call; but calling JNI_CreateJavaVM causes the program to instantly terminate. No return values, no error messages, nothing.

Yes, I know that I simply have to reinstall JRE. But nevertheless I'd like my C++ program to be prepared to such situation. If it's unable to create a Java VM, it should show a message "Please reinstall JRE". But I don't have a chance to show that message because the whole program is terminating.

Is there a way to detect such type of errors in JRE, or more generally, in a third-party library? I tried using C++ try/catch constructs, I tried using the signal function - nothing helps; the program disappears without calling any catch or signal handlers.

Is there a way to detect such JRE crash? Or: is there a way to reliably detect a crash or termination inside a third-party library?

Goblin Alchemist
  • 829
  • 5
  • 11
  • In which environment? There are OS dependent/compiler dependent ways.. (like __try __except on MS c++) – Lorenzo Dematté Feb 19 '13 at 13:38
  • Or [SetUnhandledExceptionFilter](http://msdn.microsoft.com/en-us/library/ms680634%28VS.85%29.aspx) for win32 – Lorenzo Dematté Feb 19 '13 at 13:39
  • @dema80, yes, it's Win32. Thanks for the hint, I edited the question. – Goblin Alchemist Feb 19 '13 at 13:41
  • I've found an über-hackerish instruction on [how to make a hook on ExitProcess](http://www.osix.net/modules/article/?id=728). Though, in my particular use case it's overkill. I'll resort to writing an article in our technical support database: "if the application doesn't start, reinstall JRE". :-) – Goblin Alchemist Feb 22 '13 at 10:22

1 Answers1

1

If you are using Linux/Unix: this is what I usually start with:

struct sigaction sa;
sa.sa_handler = bt_sighandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;

sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);

If you are using Microsoft C++ on windows: _try/_except will usually do the trick. It is a MSVC extension (you can tell from the double underscore), which extends standard try/catch.

Try/catch catches C++ exceptions, _try/_except will catch all the other unhandled exceptions (COM, Win32, ...). For example, it will catch null-dereferencing, memory access problems, which are likely the cause of your crash. Read here

Otherwise, in widows, try SetUnhandledExceptionFilter

EDIT: since the approach using SEH seems to fail, you may go one level up and use Vectored Exception Handling. According to this blog post on msdn, VEH is registered per-process, and it is checked before SEH.

If all fails, do not despair :) you can still turn your application into a pair debugger/debugee. That will give you total control over events, life and death of the debugee process. It is generally NOT worth the trouble, but it is an additional solution I had to use in the past. It is also not as difficult as it may seem; if anything else fails, let me know and I'll dig out some old code.

Lorenzo Dematté
  • 7,638
  • 3
  • 37
  • 77
  • Something strange is happening. try/catch, __try/__except, signal, SetUnhandledExceptionFilter all fail to handle the error. However, if I display a MessageBox before calling JNI_CreateJavaVM, all these constructs start working; specifically, signal reports a SIGSEGV error (memory access violation); then the program is able to continue running. Obviously I can't display a MessageBox every time. Maybe display an invisible window? Ugh, black magic... – Goblin Alchemist Feb 19 '13 at 15:24
  • Umm.. sounds suspiciously like a threading issue.. can you post some code showing how you use SetUnhandledExceptionFilter? (signal in Win32 uses SetUnhandledExceptionFilter underneath, IIRC) – Lorenzo Dematté Feb 19 '13 at 15:58
  • Sorry, it was not MessageBox. Instead of calling MessageBox directly, I called my error-reporting function which was also releasing the library I was calling CreateJavaVM from, so access violation was caused by bad function pointer, not the Java crash. So, in fact nothing seems to be able to catch the crash. – Goblin Alchemist Feb 22 '13 at 10:19
  • @GoblinAlchemist have you tried Vectored Exception Handling too? – Lorenzo Dematté Feb 22 '13 at 10:38