You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android NDK集成AddressSanitizer时JNI转换jstring至char*崩溃求助

问题描述

尝试在JNI代码中集成内存检测工具AddressSanitizer时触发崩溃,仅调用基础JNI函数将jstring转为char*就出现问题。

JNI代码

JNIEXPORT void JNICALL
Java_com_example_test_HelloJni_test2(JNIEnv *env, jclass clazz, jstring app_id) {
    const char *c_app_id = (*env)->GetStringUTFChars(env, app_id, NULL);
    (*env)->ReleaseStringUTFChars(env, app_id, c_app_id);
}

崩溃日志

09:29:09.742  I  AddressSanitizer can not provide additional info.
09:29:09.743  I  SUMMARY: AddressSanitizer: SEGV (/data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!/lib/arm64-v8a/libhellojni.so+0xa78) 
09:29:09.743  I  ==19624==ABORTING
09:29:09.743  A  Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 19624 (xample.asantest), pid 19624 (xample.asantest)
09:29:09.793  A  pid: 19624, tid: 19624, name: xample.asantest  >>> com.example.asantest <<<
09:29:09.793  A  Abort message: '=================================================================
                 ==19624==ERROR: AddressSanitizer: SEGV on unknown address 0x1680001f704e12fe (pc 0x007a54e7ca7c bp 0x007ff16a2550 sp 0x007ff16a24f0 T0)
                 ==19624==The signal is caused by a READ memory access.
                     #0 0x7a54e7ca78  (/data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!/lib/arm64-v8a/libhellojni.so+0xa78)
                     #1 0x7ac2005ed4  (/apex/com.android.art/lib64/libart.so+0x13ced4)
                     #2 0x7ac1ffc7e8  (/apex/com.android.art/lib64/libart.so+0x1337e8)
                     #3 0x7ac2071a94  (/apex/com.android.art/lib64/libart.so+0x1a8a94)
                     #4 0x7ac21e1460  (/apex/com.android.art/lib64/libart.so+0x318460)
                     #5 0x7ac21d778c  (/apex/com.android.art/lib64/libart.so+0x30e78c)
                     #6 0x7ac2548a88  (/apex/com.android.art/lib64/libart.so+0x67fa88)
                     #7 0x7ac1ff6994  (/apex/com.android.art/lib64/libart.so+0x12d994)
                     #8 0x7ac21ced88  (/apex/com.android.art/lib64/libart.so+0x305d88)
                     #9 0x7ac2534838  (/apex/com.android.art/lib64/libart.so+0x66b838)
                     #10 0x7ac2005ff8  (/apex/com.android.art/lib64/libart.so+0x13cff8)
                     #11 0x7ac1ffc564  (/apex/com.android.art/lib64/libart.so+0x133564)
                     #12 0x7ac2071a78  (/apex/com.android.art/lib64/libart.so+0x1a8a78)
                     #13 0x7ac241ecb8  (/apex/com.android.art/lib64/libart.so+0x555cb8)
                     #14 0x7ac239e39c  (/apex/com.android.art/lib64/libart.so+0x4d539c)
                     #15 0x7028c6f4  (/apex/com.android.art/javalib/arm64/boot.oat+0x8a6f4)
                 
                 AddressSanitizer can not provide additional info.
                 SUMMARY: AddressSanitizer: SEGV (/data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!/lib/arm64-v8a/libhellojni.so+0xa78) 
                 '
09:29:09.963  A        #01 pc 000000000004d60c  /data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!libclang_rt.asan-aarch64-android.so (offset 0x1a000) (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
09:29:09.963  A        #02 pc 000000000004c5d8  /data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!libclang_rt.asan-aarch64-android.so (offset 0x1a000) (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
09:29:09.963  A        #03 pc 00000000000a3300  /data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!libclang_rt.asan-aarch64-android.so (offset 0x1a000) (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
09:29:09.963  A        #04 pc 00000000000a2f84  /data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!libclang_rt.asan-aarch64-android.so (offset 0x1a000) (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
09:29:09.963  A        #05 pc 00000000000a2944  /data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!libclang_rt.asan-aarch64-android.so (offset 0x1a000) (BuildId: 1faa253e88d6ebbf067a087f1b98301177b89a56)
09:29:09.963  A        #07 pc 0000000000000a78  /data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!libhellojni.so (offset 0x1000) (Java_com_example_test_HelloJni_test2+40) (BuildId: 7599dcbc83b75ee9ec6d54f3d0f3af9705e6ba1d)
09:29:09.964  A        #15 pc 000000000001f230  [anon:dalvik-classes2.dex extracted in memory from /data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk!classes2.dex] (com.example.asantest.MainActivity.onBtnUseAfterFreeClick+4)
09:29:09.964  A        #30 pc 000000000008e0ea  [anon:dalvik-classes.dex extracted in memory from /data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk] (androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick+50)
09:29:09.964  A        #36 pc 000000000018c712  [anon:dalvik-classes.dex extracted in memory from /data/app/~~CvebpWoNaOlgcXHnC8RQpw==/com.example.asantest-uYPhnYp__1cAO8Eu5NNL8A==/base.apk] (com.google.android.material.button.MaterialButton.performClick+6)
---------------------------- PROCESS ENDED (19624) for package com.example.asantest ----------------------------
问题排查与解决

核心原因

崩溃发生在GetStringUTFChars调用阶段,最可能的触发点是:

  1. Java层传入了null的jstring参数,JNI直接对空指针调用JNI函数触发段错误;
  2. AddressSanitizer编译链接配置不完整,导致工具本身兼容性问题;
  3. JNI方法签名与Java层声明不匹配,参数传递异常。

修复步骤

1. 添加参数非空校验

在JNI函数开头增加null判断,避免对空指针操作:

JNIEXPORT void JNICALL
Java_com_example_test_HelloJni_test2(JNIEnv *env, jclass clazz, jstring app_id) {
    if (app_id == NULL) {
        // 抛出Java空指针异常提示调用方
        jclass exceptionClz = (*env)->FindClass(env, "java/lang/NullPointerException");
        (*env)->ThrowNew(env, exceptionClz, "app_id cannot be null");
        return;
    }
    const char *c_app_id = (*env)->GetStringUTFChars(env, app_id, NULL);
    if (c_app_id != NULL) {
        (*env)->ReleaseStringUTFChars(env, app_id, c_app_id);
    }
}

同时确保Java层调用native方法时传入的字符串不为null。

2. 检查ASAN编译配置

确保CMake/Android.mk中正确配置ASAN参数:

  • CMake配置示例:
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
    
  • 要求minSdkVersion ≥26(Android 8.0+),低版本系统对ASAN支持有限。

3. 验证JNI方法签名

确认Java层native方法声明与JNI函数完全匹配:
Java层代码应为:

public static native void test2(String app_id);

包名、类名、方法名、参数类型必须严格对应,签名不匹配会导致参数传递错乱。

验证

修复后重新编译安装应用,触发JNI调用,确认崩溃不再发生。若仍有问题,可暂时关闭ASAN排查是否为工具兼容性问题,再逐步定位。


内容的提问来源于stack exchange,提问作者Sucer Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 18:26:17