sdu*_*key 3 java-native-interface android exception-handling native-code
我的项目使用捕获崩溃的模块并在android系统中发送.处理本机崩溃时,本机代码将执行某些操作,然后从JNI执行Java调用.它适用于Dalvik.但它在使用ART的5.0以上的Android版本中失败了.因为ART在本机信号处理期间阻止来自JNI的任何Java调用.它说ART信号处理使用备用信号堆栈,所以在信号处理过程中,不能调用java方法吗?还有其他方法吗?
流:
1.Java调用本机方法,但本机方法崩溃.
2.本机崩溃处理程序捕获信号以处理崩溃.
3.在崩溃处理过程中,调用JNI方法但失败了
12-31 20:36:02.516 7845-7957 A/art: art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI IsSameObject called with pending exception 'java.lang.StackOverflowError' thrown in...
in call to IsSameObject
stack=0x9fff8000-0x9fffa000 stackSize=1036KB
Run Code Online (Sandbox Code Playgroud)
参考:https://code.google.com/p/android/issues/detail?
id = 162663如果有人使用ART和/或Bionic可以调查一下,那就太好了.
您的项目依赖于未定义的行为.
任何信号处理程序都可以安全地只调用异步信号安全函数.任何其他函数调用都会调用未定义的行为.在任何情况下依靠Java/Dalvik/ART虚拟机将其自身限制为异步信号安全函数调用是不切实际的,并且很可能只是简单的错误.
您可以随时调用任意信号的处理程序,使VM处于任何可能的状态.没有办法从JNI信号处理程序安全地进行Java调用,并且期望任何人甚至尝试支持这样的调用是不合理的 - synchronized如果允许信号处理程序允许调用synchronized,VM的设计者如何允许信号中断任何方法同一个对象?如果他们这样做,他们就会违背语言的含义而破坏语言synchronized.但如果他们不这样做,他们就会允许死锁,因为这样的调用会试图锁定一个永远无法解锁的对象,因为信号会中断处理.
简而言之,从信号处理程序通过JNI进行的Java调用从根本上说是不可支持的.
他们过去为你工作的事实只能让你期望他们会继续这样做.
你过去很幸运.
它不再有效,你不能指望它将来有用.
即使你以某种方式破解它为你工作,它仍然是根本不健全的.根据POSIX标准,唯一可以在信号处理程序中安全地进行的调用是:
下表定义了一组函数,这些函数应该是信号的可重入或不可中断的,并且应该是异步信号安全的.因此,应用程序可以无限制地调用信号捕获功能:
Run Code Online (Sandbox Code Playgroud)_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卷定义的所有功能在信号捕获功能调用或中断时应按照定义运行,但有一个例外:当信号中断不安全功能和信号时 - catch函数调用一个不安全的函数,行为是未定义的.
由于无法保证在信号处理程序中通过JNI进行Java调用只能调用异步信号安全函数,因此除了未定义的行为之外,你无法预料到任何事情.
| 归档时间: |
|
| 查看次数: |
908 次 |
| 最近记录: |