бросить, поймать, сигосакция macosx - PullRequest
1 голос
/ 28 января 2012

Вставленный здесь код является попыткой отобразить SIGSEGV в исключение Java.До того, как кто-то станет слишком взволнован, да, я знаю, это нарушает различные утверждения в различных стандартах.Он предназначен как полностью временная тактика, чтобы отследить упрямую ошибку.

На Mac, по крайней мере, это не работает.бросок C ++ в вызовах функций sigaction 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;
}

1 Ответ

1 голос
/ 13 февраля 2012

Взгляните на собственные биты JNA, которые используют setjmp / longjmp для перевода SIGSEGV в исключение Java.

https://github.com/twall/jna/blob/master/native/protect.h

Обратите внимание, что когда вы начинаете добавлять свои собственные обработчики сигналов, вам нужно правильно цеплять сигналы, обычно обрабатываемые виртуальной машиной (см. http://download.oracle.com/javase/6/docs/technotes/guides/vm/signal-chaining.html).

Вам следует внимательно прочитать справочные страницы для подтверждения того, что вы должны и чего не должны делать в обработчике сигналов. Есть только несколько системных вызовов, которые являются «безопасными», и я не припоминаю, чтобы видел что-либо о создании исключений C ++ из контекста обработчика сигнала, являющегося поддерживаемой операцией. Вполне возможно, что информация о размотке стека исключений в C ++ может быть недопустимой или недоступной в контексте обработчика сигналов.

...