Ваш проект полагается на неопределенное поведение.
Любой обработчик сигналов может безопасно выполнять только вызовы асинхронных сигнально-безопасных функций. Любой другой вызов функции вызывает неопределенное поведение. Полагаться на виртуальную машину Java / Dalvik / ART для ограничения себя вызовами функций, безопасных для асинхронных сигналов, в любой ситуации в лучшем случае нереально и, скорее всего, просто неверно.
Ваш обработчик произвольного сигнала может быть вызван в любое время, оставив виртуальную машину в любом возможном состоянии. Невозможно безопасно выполнять вызовы Java из обработчика сигналов JNI, и неразумно ожидать, что кто-то даже попытается поддержать такие вызовы - как могут конструкторы виртуальной машины разрешить сигналу прерывать любой метод synchronized
, если обработчику сигнала было разрешено совершать вызовы synchronized
на том же объекте? Если бы они сделали это, они бы нарушили язык, нарушив само значение synchronized
. Но если бы они этого не сделали, они разрешили бы взаимоблокировки, поскольку такие вызовы будут пытаться заблокировать объект, который никогда не может быть разблокирован, потому что сигнал прервал обработку.
Короче говоря, вызовы Java через JNI из обработчика сигналов принципиально не поддерживаются.
Тот факт, что раньше они работали на вас, только давал вам надежду на то, что они будут продолжать это делать.
Тебе раньше везло.
Он больше не работает, и вы не можете ожидать, что он будет работать в будущем.
И даже если вы каким-то образом заставите его работать на себя, это все равно фундаментально несостоятельно. Единственные безопасные вызовы из обработчика сигналов согласно стандарту POSIX, это:
В следующей таблице определяется набор функций, которые должны быть либо повторно входящими, либо не прерываться сигналами и должны быть безопасными для асинхронных сигналов. Поэтому приложения могут вызывать их без ограничений из функций перехвата сигналов:
_Exit()
_exit()
abort()
accept()
access()
aio_error()
aio_return()
aio_suspend()
alarm()
bind()
cfgetispeed()
cfgetospeed()
cfsetispeed()
cfsetospeed()
chdir()
chmod()
chown()
clock_gettime()
close()
connect()
creat()
dup()
dup2()
execle()
execve()
fchmod()
fchown()
fcntl()
fdatasync()
fork()
fpathconf()
fstat()
fsync()
ftruncate()
getegid()
geteuid()
getgid()
getgroups()
getpeername()
getpgrp()
getpid()
getppid()
getsockname()
getsockopt()
getuid()
kill()
link()
listen()
lseek()
lstat()
mkdir()
mkfifo()
open()
pathconf()
pause()
pipe()
poll()
posix_trace_event()
pselect()
raise()
read()
readlink()
recv()
recvfrom()
recvmsg()
rename()
rmdir()
select()
sem_post()
send()
sendmsg()
sendto()
setgid()
setpgid()
setsid()
setsockopt()
setuid()
shutdown()
sigaction()
sigaddset()
sigdelset()
sigemptyset()
sigfillset()
sigismember()
sleep()
signal()
sigpause()
sigpending()
sigprocmask()
sigqueue()
sigset()
sigsuspend()
sockatmark()
socket()
socketpair()
stat()
symlink()
sysconf()
tcdrain()
tcflow()
tcflush()
tcgetattr()
tcgetpgrp()
tcsendbreak()
tcsetattr()
tcsetpgrp()
time()
timer_getoverrun()
timer_gettime()
timer_settime()
times()
umask()
uname()
unlink()
utime()
wait()
waitpid()
write()
Все функции, не указанные в приведенной выше таблице, считаются небезопасными в отношении сигналов. При наличии сигналов все функции, определенные в этом томе IEEE Std 1003.1-2001, должны вести себя так, как определено, когда вызываются из или прерываются функцией перехвата сигналов, за одним исключением: когда сигнал прерывает небезопасную функцию и сигнал- функция перехвата вызывает небезопасную функцию, поведение не определено.
Поскольку вы не можете гарантировать, что вызов Java через JNI из обработчика сигналов будет вызывать только асинхронные сигнально-безопасные функции, вы не можете ожидать чего-либо, кроме неопределенного поведения.
person
Andrew Henle
schedule
01.01.2016