Как перехватить SIGSEGV, SIGALRM и SIGFPE с помощью sigaction() при использовании JNI?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Как перехватить SIGSEGV, SIGALRM и SIGFPE с помощью sigaction() при использовании JNI?

Сообщение Anonymous »

Моя цель — перехватить SIGSEGV (бесконечная рекурсия), SIGALRM (бесконечные циклы, вызываемые таймером) и SIGFPE (деление на 0) из машинного кода, поскольку я хочу предотвратить сбой или зависание Minecraft (Java) всякий раз, когда мод, написанный на моем скомпилированном языке моддинга, имеет такие проблемы.
Я смог успешно использовать свой язык моддинга в других программах ( написано в C/C++/Python) с использованием sigaction() и sigsetjmp(), но в Java это не так просто, как описано в этом ответе на Stack Overflow:

Виртуальная машина Java (по крайней мере, реализация Oracles, которая также включает OpenJDK) использует сигналы POSIX для внутренней связи, поэтому она устанавливает обработчики сигналов, например. для СИГСЕГВ. Это означает, что для правильной работы виртуальная машина Java должна получать и проверять любые SIGSEGV, возникающие в процессе, чтобы отличать «коммуникационные» SIGSEGV от реальных, которые могут быть программными ошибками.
Но обработчики сигналов — это глобальный ресурс; внутри процесса любой собственный код может устанавливать обработчики сигналов и заменять те, которые установлены на виртуальной машине Java.
Чтобы решить эту проблему (установленные пользователем обработчики сигналов заменяют JavaVM обработчики сигналов) и для размещения пользовательского кода, который может иметь причину для установки обработчиков сигналов, Java VM использует «цепочку сигналов», что по сути означает, что обработчики сигналов (VM и пользователи) связаны друг с другом: обработчики сигналов JavaVM запускаются первыми; если они считают, что сигнал не представляет интереса для виртуальной машины, она передает сигнал обработчику пользователя.
Libjsig.so является ответом на эту проблему: он заменяет системный сигнал API (sigaction() и т. д.) со своими собственными версиями, а также любой пользовательский код, пытающийся установить обработчик сигнала, не заменит глобальный обработчик сигнала, но обработчик пользователя будет связан с (уже установленным) обработчиком сигнала виртуальной машины Java.

Обратите внимание, что невероятно легко случайно ввести неопределенное поведение при вызове siglongjmp()из обработчика сигнала, как описано в разделе «ИСПОЛЬЗОВАНИЕ ПРИЛОЖЕНИЯ» эту страницу. Вот почему мой язык моддинга блокирует (используя sigprocmask) и отключает обработчики сигналов в стратегические моменты.
В цитате рекомендуется использовать jsig, чего легко добиться, указав LD_PRELOAD= /libjsig.so перед командой java.
Однако использование jsig гарантирует, что JVM получит SIGSEGV до того, как это сделает мой собственный обработчик. Поскольку JVM считает его невосстановимым и, очевидно, не хочет перекладывать ответственность за обработку SIGSEGV на мой собственный обработчик, она не вызывает его, что приводит к сбою.
Если я не использую jsig, он жалуется, что хочет, чтобы я его использовал, поскольку JVM периодически проверяет, не был ли подделан обработчик сигнала:

Код: Выделить всё

Warning: SIGSEGV handler modified!
Signal Handlers:
SIGSEGV: segv_handler in libfoo.so, mask=11111111011111111101111111111110, flags=SA_ONSTACK, unblocked
*** Handler was modified!
*** Expected: javaSignalHandler in libjvm.so, mask=11100100110111111111111111111110, flags=SA_RESTART|SA_SIGINFO
SIGBUS: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked
SIGFPE: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked
SIGPIPE: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked
SIGXFSZ: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked
SIGILL: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked
SIGUSR2: SR_handler in libjvm.so, mask=00000000000000000000000000000000, flags=SA_RESTART|SA_SIGINFO, unblocked
SIGHUP: UserHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked
SIGINT: UserHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked
SIGTERM: UserHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked
SIGQUIT: UserHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, blocked
SIGTRAP: SIG_DFL, mask=00000000000000000000000000000000, flags=none, unblocked
Consider using jsig library.
Он жалуется, потому что мой код C нарушает собственный обработчик SIGSEGV JVM, который он использует внутри себя для выполнения изящных задач, таких как оптимизация проверки на ноль, что объясняет, почему это приводит к моя игра время от времени вылетает.
Как мне полностью восстановиться после безобидных сигналов SIGSEGV, SIGALRM и SIGFPE, которые собственный код C, не нарушая работу JVM?

Подробнее здесь: https://stackoverflow.com/questions/793 ... -using-jni
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как перехватить SIGSEGV, SIGALRM и SIGFPE с помощью sigaction() при использовании JNI?
    Anonymous » » в форуме JAVA
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Как мне перехватить SIGSEGV с помощью sigaction() при использовании JNI?
    Anonymous » » в форуме JAVA
    0 Ответы
    17 Просмотры
    Последнее сообщение Anonymous
  • Как мне перехватить SIGSEGV с помощью sigaction() при использовании JNI?
    Anonymous » » в форуме JAVA
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • Как мне перехватить SIGSEGV с помощью sigaction() при использовании JNI?
    Anonymous » » в форуме JAVA
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Как мне перехватить SIGSEGV с помощью sigaction() при использовании JNI?
    Anonymous » » в форуме JAVA
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»