Android NDK调试模式触发SIGSEGV无效地址错误求助
关于Android NDK调试时触发SIGSEGV的原因分析
嘿,我之前调试JNI代码时也碰到过类似的诡异问题,结合你的代码和现象,大概能把原因说清楚:
核心原因:旧Android版本调试器的JNI上下文处理bug
你遇到的SIGSEGV (fault address: 0x8)错误,本质是JNIEnv指针被错误置为NULL后,尝试访问其内部函数指针导致的——(*env)->NewStringUTF这个调用里,env是空指针的话,访问它偏移8字节的位置(JNIEnv结构体里的函数指针表偏移)就会触发0x8地址的段错误。
为什么正常运行没问题,只有调试时会出现?而且Android 9及以上就恢复正常了?这是因为:
- 旧版本Android(9以下)的调试器(配合对应版本的NDK)在处理静态native方法的调试监视时,存在上下文维护的bug:当你查看监视变量时,调试器会尝试在当前线程环境中获取JNI相关状态,但没有正确处理静态native方法的调用上下文,导致JNIEnv指针在调试场景下失效变为NULL。
- Android 9及以上的系统调试栈(包括LLDB和NDK的适配层)修复了这个JNI调试上下文的问题,所以调试时不会再触发这个错误。
额外提醒:你的JNI代码有个笔误
看你的C代码,第三个JNI函数的签名多了个多余的J前缀:
JNIEXPORT jstring JNICALL JJava_com_my_company_co_utilities_UtilFuncs_getKeyOne(JNIEnv *env, jobject instance) { return (*env)-> NewStringUTF(env, "my_key_1"); }
正确的签名应该是Java_com_my_company_co_utilities_UtilFuncs_getKeyOne。不过你说正常运行没问题,应该是这个函数暂时没被调用到,所以没暴露问题,但后续如果用到这个函数,会直接触发"找不到native方法"的崩溃,建议赶紧修正。
内容的提问来源于stack exchange,提问作者Ryan McCaffrey
相关产品推荐
相关产品推荐

