我的项目使用捕获崩溃的模块并在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
参考:https://code.google.com/p/android/issues/detail?id=162663
如果有人和ART和/或Bionic一起工作,那就太好了。
答案 0 :(得分:6)
您的项目依赖于未定义的行为。
任何信号处理程序都可以安全地对 调用异步信号安全函数。任何其他函数调用都会调用未定义的行为。在任何情况下依赖Java / Dalvik / ART虚拟机将其自身限制为异步信号安全函数调用是不切实际的,而且很可能只是简单的错误。
可以随时调用任意信号的处理程序,使VM处于任何可能的状态。没有办法安全地从JNI信号处理程序进行Java调用,并且期望任何人甚至尝试支持这样的调用是不合理的 - VM的设计者如何允许信号中断任何{{1方法,如果允许信号处理程序在同一个对象上进行调用synchronized
?如果他们这样做,他们就会违反synchronized
的含义而破坏语言。但如果他们没有这样做,他们就会允许死锁,因为这样的调用会试图锁定一个永远无法解锁的对象,因为信号会中断处理。
简而言之,从信号处理程序通过JNI进行的Java调用从根本上说是不可支持的。
他们过去为你工作的事实只能让你期望他们会继续这样做。
过去你很幸运。
它不再有效,你不能指望它在将来有效。
即使你以某种方式破解它为你工作,它仍然根本不健全。根据{{3}},信号处理程序中唯一可安全调用的调用是:
下表定义了一组应该是的函数 信号可重入或不可中断,应为 异步信号安全。因此,应用程序可以调用它们,而不是 限制,来自信号捕捉功能:
synchronized
上表中未包含的所有功能都被认为对信号不安全。在存在信号的情况下,由IEEE Std 1003.1-2001卷定义的所有功能在信号捕获功能调用或中断时应按照定义运行,但有一个例外:当信号中断不安全功能和信号时 - catch函数调用一个不安全的函数,行为是未定义的。
由于无法保证在信号处理程序中通过JNI进行Java调用只会调用异步信号安全函数,所以除了未定义之外,你无法预料到任何事情。行为。