ここに貼り付けられたコードは、SIGSEGVをJava例外にマップする試みです。誰もが興奮する前に、はい、私は知っている、これは様々な基準の様々な声明をtrangresses。これは、頑固なバグを追跡するための完全に一時的な戦術として意図されています。throw、catch、sigaction macosx
Macでは、少なくとも動作しません。 sigaction関数のC++スローがterminateを呼び出します。
私はこの質問を投稿して、誰かがこれをうまく調整する方法を知っているかどうか尋ねます。
#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;
}
ああ、こんにちは、私は15年前にロングジャムでこれを書いていました。それでも最適な解決策はありますか?ところで、この質問のコードはLinuxで動作します。 – bmargulies
FWIWでは、JNAの実装はさまざまなプラットフォームで動作しますが、スレッドセーフではありません(コンテキストの保存には静的変数を使用し、スレッドセーフな動作ではスレッドローカルにする必要があります)。 OSXの動作は、例外コンテキストがシグナルハンドラ内で有効ではないことを示しているようです。そのため、_terminate()が呼び出されるのです。 – technomage