The code pasted here is an attempt to map a SIGSEGV to a java exception. Before anyone gets too excited, yes, I know, this trangresses various statements in various standards. It's intended as an entirely temporary tactic to track down a stubborn bug.
On a Mac, at least, it doesn't work. the C++ throw in the sigaction function calls terminate.
I post this question to ask if anyone knows how to tweak this to work.
#include <stdio.h>
#include <signal.h>
#include "com_github_bimargulies_jnisigsegv_Native.h"
static JavaVM* staticJvm;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
staticJvm = jvm;
return JNI_VERSION_1_6;
}
/* there has to be a catch. */
struct SomethingToThrow {};
void handler_function(int sig, struct __siginfo* si, void *) {
JNIEnv *env = 0;
staticJvm->GetEnv((void **)&env, JNI_VERSION_1_6);
jclass newExcCls = env->FindClass("java/lang/RuntimeException");
env->ThrowNew(newExcCls, "SIGSEGV");
fprintf(stderr, "About to throw at the catch ... block\n");
fflush(stderr);
throw SomethingToThrow();
}
JNIEXPORT void JNICALL Java_com_github_bimargulies_jnisigsegv_Native_setupHandler(JNIEnv *, jclass) {
struct sigaction sa;
struct sigaction oldsa;
sa.sa_sigaction = handler_function;
sa.sa_mask = 0;
sa.sa_flags = SA_SIGINFO;
int r = sigaction(SIGSEGV, &sa, &oldsa);
fprintf(stderr, "Signaction returned %d\n", r);
fflush(stderr);
}
JNIEXPORT void JNICALL Java_com_github_bimargulies_jnisigsegv_Native_getAnError
(JNIEnv *, jclass, jstring) {
/* First experiment, just get a sigsegv */
char * p = 0;
try {
*p = 1;
} catch (...) {
fprintf(stderr, "Caught something\n");
}
return;
}
Take a look at the native bits of JNA, which uses setjmp/longjmp to translate SIGSEGV into a Java exception.
https://github.com/twall/jna/blob/master/native/protect.h
Note that when you start adding your own signal handlers, you need to properly chain signals normally handled by the VM (see http://download.oracle.com/javase/6/docs/technotes/guides/vm/signal-chaining.html).
You should read carefully the man pages for sigaction to review what you should and should not do within a signal handler. There are only a few system calls that are "safe", and I don't recall seeing anything about throwing C++ exceptions from the context of the signal handler being a supported operation. It's quite possible that your C++ exception stack unwind information may not be valid or accessible in the context of the signal handler.