以下是堆栈跟踪。崩溃起源的源代码是here .
我跟踪堆栈跟踪直到 android 的源代码是 here .
我无法理解这意味着什么以及为什么它只是有时发生。任何帮助,将不胜感激。很高兴分享更多详细信息。
我们已经能够在 Android 7.0 设备上重现此崩溃。但它并不一致。
06-28 19:09:26.147 5696 5696 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-28 19:09:26.147 5696 5696 F DEBUG : Native Crash TIME: 265472
06-28 19:09:26.147 5696 5696 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-28 19:09:26.148 5696 5696 F DEBUG : Build fingerprint: 'Karbonn/K9_Smart_Eco/K9_Smart_Eco:7.0/NRD90M/1498048597:user/release-keys'
06-28 19:09:26.148 5696 5696 F DEBUG : Revision: '0'
06-28 19:09:26.148 5696 5696 F DEBUG : ABI: 'arm'
06-28 19:09:26.148 5696 5696 F DEBUG : pid: 5587, tid: 5689, name: JS Thread >>> com.hashcube.sqmtest <<<
06-28 19:09:26.149 5696 5696 F DEBUG : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
06-28 19:09:26.152 5696 5696 F DEBUG : Abort message: 'art/runtime/java_vm_ext.cc:470] JNI DETECTED ERROR IN APPLICATION: thread Thread[54,tid=5689,Native,Thread*=0x8a4de500,peer=0x12dc89d0,"JS Thread"] using JNIEnv* from thread Thread[54,tid=5689,Native,Thread*=0x8a4de500,peer=0x12dc89d0,"JS Thread"]'
06-28 19:09:26.152 5696 5696 F DEBUG : r0 00000000 r1 00001639 r2 00000006 r3 00000008
06-28 19:09:26.152 5696 5696 F DEBUG : r4 899ff978 r5 00000006 r6 899ff920 r7 0000010c
06-28 19:09:26.152 5696 5696 F DEBUG : r8 00000000 r9 add696a4 sl 00000ac4 fp add2eecf
06-28 19:09:26.153 5696 5696 F DEBUG : ip 0000000b sp 899feb50 lr b039a597 pc b039cdf4 cpsr 20070010
06-28 19:09:26.192 5696 5696 F DEBUG :
06-28 19:09:26.192 5696 5696 F DEBUG : backtrace:
06-28 19:09:26.193 5696 5696 F DEBUG : #00 pc 00049df4 /system/lib/libc.so (tgkill+12)
06-28 19:09:26.193 5696 5696 F DEBUG : #01 pc 00047593 /system/lib/libc.so (pthread_kill+34)
06-28 19:09:26.193 5696 5696 F DEBUG : #02 pc 0001d855 /system/lib/libc.so (raise+10)
06-28 19:09:26.193 5696 5696 F DEBUG : #03 pc 000193a1 /system/lib/libc.so (__libc_android_abort+34)
06-28 19:09:26.193 5696 5696 F DEBUG : #04 pc 00017014 /system/lib/libc.so (abort+4)
06-28 19:09:26.193 5696 5696 F DEBUG : #05 pc 003188f5 /system/lib/libart.so (_ZN3art7Runtime5AbortEv+252)
06-28 19:09:26.194 5696 5696 F DEBUG : #06 pc 000b4e79 /system/lib/libart.so (_ZN3art10LogMessageD2Ev+864)
06-28 19:09:26.194 5696 5696 F DEBUG : #07 pc 00238971 /system/lib/libart.so (_ZN3art9JavaVMExt8JniAbortEPKcS2_+1664)
06-28 19:09:26.194 5696 5696 F DEBUG : #08 pc 00238b63 /system/lib/libart.so (_ZN3art9JavaVMExt9JniAbortVEPKcS2_St9__va_list+58)
06-28 19:09:26.194 5696 5696 F DEBUG : #09 pc 000ca81b /system/lib/libart.so (_ZN3art11ScopedCheck6AbortFEPKcz+46)
06-28 19:09:26.194 5696 5696 F DEBUG : #10 pc 000ca305 /system/lib/libart.so (_ZN3art11ScopedCheck11CheckThreadEP7_JNIEnv+104)
06-28 19:09:26.194 5696 5696 F DEBUG : #11 pc 000c941f /system/lib/libart.so (_ZN3art11ScopedCheck22CheckPossibleHeapValueERNS_18ScopedObjectAccessEcNS_12JniValueTypeE+26)
06-28 19:09:26.195 5696 5696 F DEBUG : #12 pc 000c88fb /system/lib/libart.so (_ZN3art11ScopedCheck5CheckERNS_18ScopedObjectAccessEbPKcPNS_12JniValueTypeE+802)
06-28 19:09:26.195 5696 5696 F DEBUG : #13 pc 000cdd79 /system/lib/libart.so (_ZN3art8CheckJNI8GetFieldEPKcP7_JNIEnvP8_jobjectP9_jfieldIDbNS_9Primitive4TypeE+496)
06-28 19:09:26.195 5696 5696 F DEBUG : #14 pc 000c2eef /system/lib/libart.so (_ZN3art8CheckJNI11GetIntFieldEP7_JNIEnvP8_jobjectP9_jfieldID+42)
06-28 19:09:26.195 5696 5696 F DEBUG : #15 pc 0009a35c /data/app/com.hashcube.sqmtest-1/lib/arm/libtealeaf.so (_Z19navigator_info_initv+252)
06-28 19:09:26.195 5696 5696 F DEBUG : #16 pc 00084ca0 /data/app/com.hashcube.sqmtest-1/lib/arm/libtealeaf.so (_Z25js_navigator_get_templatev+100)
06-28 19:09:26.196 5696 5696 F DEBUG : #17 pc 0007caf0 /data/app/com.hashcube.sqmtest-1/lib/arm/libtealeaf.so (init_js+740)
06-28 19:09:26.196 5696 5696 F DEBUG : #18 pc 00089dc4 /data/app/com.hashcube.sqmtest-1/lib/arm/libtealeaf.so (core_init_js+36)
06-28 19:09:26.196 5696 5696 F DEBUG : #19 pc 00099a28 /data/app/com.hashcube.sqmtest-1/lib/arm/libtealeaf.so (Java_com_tealeaf_NativeShim_initJS+180)
06-28 19:09:26.196 5696 5696 F DEBUG : #20 pc 0088494d /data/app/com.hashcube.sqmtest-1/oat/arm/base.odex (offset 0x82e000)
最佳答案
看起来你的函数是从 native 线程调用的,它导致调用 FindClass 和其他试图使用 java 代码的 JNI 方法崩溃
06-28 19:09:26.194 5696 5696 F DEBUG : #09 pc 000ca81b /system/lib/libart.so (_ZN3art11ScopedCheck6AbortFEPKcz+46)
06-28 19:09:26.194 5696 5696 F DEBUG : #10 pc 000ca305 /system/lib/libart.so (_ZN3art11ScopedCheck11CheckThreadEP7_JNIEnv+104)
在文件 jni/platform/native_shim.cpp 中的代码中,我可以看到:
static JNIEnv* get_env() {
JNIEnv* env;
static_vm->AttachCurrentThread(&env, NULL);
return env;
}
native_shim *get_native_shim() {
if(shim.instance == NULL) {
LOG("{native} ERROR: Tried to get native shim when there wasn't one");
#if DEBUG
*((int*)0) = -1;
#else
exit(1);
#endif
}
shim.env = get_env();
return &shim;
}
在 static_vm->AttachCurrentThread(&env, NULL); 行中,您尝试使用空 JNIEnv 指针将当前线程附加到 JVM。您已经声明了它,但从未分配过。我在您的文件中寻找 JNI_OnLoad 函数,但没有找到。最好在此方法中获取一次 JavaVM 并将其存储在某个地方,这样您就可以在需要的地方从中获取 JNIEnv 指针。它的功能可能如下所示:
JavaVM *java_machine;
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
java_machine = vm;
}
int get_env(JNIEnv **g_env) {
int getEnvStat = java_machine->GetEnv((void **) g_env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED) {
if (java_machine->AttachCurrentThread(g_env, nullptr) != 0) {
__android_log_print(ANDROID_LOG_ERROR, "GetEnvironmentRoutine", "FAILED ATTACH THREAD");
return 2; //Failed to attach
}
return 1; //Attached. Need detach
}
return 0;//Already attached
}
并且必须在方法的最后调用java_machine->DetachCurrentThread();,因为如果附加的 native 线程在没有分离的情况下退出,将导致java机器崩溃。
您还可以为此编写 RAII 包装器,以确保您的线程已在所有方法分支上分离。
class attached_env final {
public:
attached_env() {
auto resCode = get_env(&mEnv);
if (resCode == 2)
throw std::runtime_error("Cannot retrieve JNI environment");
needDetach = (resCode == 1);
}
~attached_env() {
if (needDetach) {
java_machine->DetachCurrentThread();
}
}
JNIEnv *env() const noexcept {
return mEnv;
}
private:
JNIEnv *mEnv;
bool needDetach;
};
template<typename Callable>
auto call_in_attached_thread(Callable func) {
attached_env env;
return func(env.env());
}
所以你的方法可能看起来像这样(需要精确,见下文):
navigator_info* navigator_info_init() {
call_in_attached_thread([=](auto env) {
jclass display_metrics_class = (jclass)env->FindClass("android/util/DisplayMetrics");//WILL NOT WORK! SEE BELOW
jfieldID density_dpi = env->GetFieldID(display_metrics_class, "densityDpi", "I");
jfieldID xdpi = env->GetFieldID(display_metrics_class, "xdpi", "F");
//And so on...
...
});
接下来需要注意的是,如果调用堆栈未在您的 Java 代码中启动,则您不能使用 FindClass 函数来查找自定义类。因此,在大多数情况下,在 native 线程中(无论是否附加)调用 FindClass 都会导致崩溃。您需要在 JNI_OnLoad 中找到类并使用全局 java 引用将它们存储在全局变量中:
jclass globalDisplayMetricsClassRef;
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
//
//previous code here
//
auto localRef = env->FindClass("android/util/DisplayMetrics");
globalDisplayMetricsClassRef = (jclass)env->NewGlobalRef(localRef);
}
最后我们得到:
navigator_info* navigator_info_init() {
call_in_attached_thread([=](auto env) {
jfieldID density_dpi = env->GetFieldID(globalDisplayMetricsClassRef, "densityDpi", "I");
jfieldID xdpi = env->GetFieldID(display_metrics_class, "xdpi", "F");
//And so on...
...
});
更新:
来自 ART CheckThread 函数的一段代码
// Verify that the current thread is (a) attached and (b) associated with
// this particular instance of JNIEnv.
if (soa_.Env() != threadEnv) {
if (soa_.Vm()->work_around_app_jni_bugs) {
// If we're keeping broken code limping along, we need to suppress the abort...
LOG(ERROR) << "APP BUG DETECTED: thread " << *self << " using JNIEnv* from thread " << *soa_.Self();
} else {
JniAbortF(function_name_, "thread %s using JNIEnv* from thread %s",
ToStr<Thread>(*self).c_str(), ToStr<Thread>(*soa_.Self()).c_str());
return;
}
}
关于java - native 崩溃 : JNI DETECTED ERROR IN APPLICATION: [thread] using JNIEnv* from [thread],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51099200/
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe
protect_from_forgery默认Rails6应用程序不包含在我的应用程序Controller中,但是有嵌入式ruby在主应用程序布局中。这是否意味着protect_from_forgery方法已经被抽象并且在应用程序Controller中不再明确需要?我买了实用程序员的Rails6一书,我唯一能找到的是“csrf_meta_tags()方法设置了防止跨站点请求伪造攻击所需的所有幕后数据”。 最佳答案 对于rails5.2和更高版本,默认情况下在ActionController::Base上启用。查看此提交:https
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht