这里粘贴的代码试图将SIGSEGV映射到java异常。在任何人太兴奋之前,是的,我知道,这以不同的标准改变了不同的声明。它的目的是作为一种完全临时的策略来追踪顽固的bug。
至少在Mac上,它不能工作。在sigaction函数中抛出的C++调用将终止。
我发布这个问题是想问是否有人知道如何调整它来工作。
#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;
}发布于 2012-02-14 00:53:09
看看JNA的本机代码,它使用setjmp/longjmp将SIGSEGV转换为Java异常。
https://github.com/twall/jna/blob/master/native/protect.h
请注意,当您开始添加自己的信号处理程序时,需要正确地链接通常由VM处理的信号(请参阅http://download.oracle.com/javase/6/docs/technotes/guides/vm/signal-chaining.html)。
您应该仔细阅读sigaction的手册页,以回顾您应该和不应该在信号处理程序中执行的操作。只有几个系统调用是“安全的”,我不记得从信号处理程序的上下文中看到过任何抛出C++异常的受支持操作。您的C++异常堆栈展开信息很可能在信号处理程序的上下文中是无效的或不可访问的。
https://stackoverflow.com/questions/9041100
复制相似问题