美文网首页Android开发
signal 11 (SIGSEGV)错误排查

signal 11 (SIGSEGV)错误排查

作者: yuLiangC | 来源:发表于2019-02-16 16:49 被阅读4次

    jni调试最蛋疼的就是signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4这种错误,爆出来完全不知道是哪句代码造成的,很难定位到问题所在,网上很多人说是内存原因,还有说是空指针,不一而论。
    我的错误是这样的:

    02-16 14:54:53.041 20897-20897/? I/AEE/AED: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
    02-16 14:54:53.058 20897-20897/? I/AEE/AED:     r0 00000001  r1 00000002  r2 00000000  r3 0000002f
    02-16 14:54:53.058 20897-20897/? I/AEE/AED:     r4 00000000  r5 f4489000  r6 f4400000  r7 f6fb3c0c
    02-16 14:54:53.058 20897-20897/? I/AEE/AED:     r8 f48000c0  r9 f6fb3c0c  sl 00000001  fp 00000002
    02-16 14:54:53.058 20897-20897/? I/AEE/AED:     ip f6fb3c24  sp dc144060  lr 00000000  pc f6f7f566  cpsr 600f0030
    02-16 14:54:53.059 20897-20897/? I/AEE/AED: backtrace:
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #00 pc 00042566  /system/lib/libc.so (je_arena_dalloc_bin_locked+365)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #01 pc 0004fa0b  /system/lib/libc.so (je_tcache_bin_flush_small+234)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #02 pc 0004a33f  /system/lib/libc.so (ifree+446)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #03 pc 00035775  /data/app/我的包名-1/lib/arm/libjni-lib.so (std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >::~basic_string()+148)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #04 pc 00086087  /data/app/我的包名-1/lib/arm/libjni-lib.so (WPZHandler::OnRspQryPosition(TradingLibFast::RspQryPositionResponse*)+2518)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #05 pc 0004451d  /data/app/我的包名-1/lib/arm/libjni-lib.so (TradingLibFast::TLClient::HandleMessage(TradingLibFast::Message&)+964)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #06 pc 00041083  /data/app/我的包名-1/lib/arm/libjni-lib.so (TradingLibFast::TLClient::RecvFun()+226)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #07 pc 00066cfb  /data/app/我的包名-1/lib/arm/libjni-lib.so (fastdelegate::FastDelegate0<bool>::operator()() const+94)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #08 pc 00066889  /data/app/我的包名-1/lib/arm/libjni-lib.so (TradingLibFast::TLThread::ProcessInThread()+68)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #09 pc 00066837  /data/app/我的包名-1/lib/arm/libjni-lib.so (TradingLibFast::ThreadFunc(void*)+26)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #10 pc 00017003  /system/lib/libc.so (__pthread_start(void*)+30)
    02-16 14:54:53.059 20897-20897/? I/AEE/AED:     #11 pc 0001506f  /system/lib/libc.so (__start_thread+6)
    

    然后就是nativeCrashListener,这个log其实已经很清晰了,记得一定不要过滤,选择no Filters,日志级别选择Verbose最低级别,这样才能看到最全的log信息。je_arena_dalloc_bin_locked显示就是内存处理出问题了,jni代码出问题导致了系统错误。再往下包含“我的包名”的log信息就显示了错误的具体位置,越上面就是越具体的位置,越下面范围就越广,这里大致就定位了问题代码大概在哪几行。不过这几行我纠结了许久,因为觉得没有问题,闪退只是偶现,后来看到另外一篇文章:常见 core dump 原因分析signal 11 - SIGSEGV,说signal 11 (SIGSEGV)是由于内存释放不当(多次释放或者空释放)或者空指针引起的,遂检查,终于发现了问题:
    在调用NewStringUTF方法的时候使用了ReleaseStringUTFChars进行释放,这个释放内存的方法并不能在此处使用,应该使用DeleteLocalRef来释放引用即可。
    jni具体内存释放对应方法如下:
    总体原则:释放所有对object的引用

    1.FindClass
    例如,

    jclass ref= (env)->FindClass("java/lang/String"); 
    env->DeleteLocalRef(ref); 
    

    2.NewString/ NewStringUTF/NewObject/NewByteArray
    例如,

    jstring     (*NewString)(JNIEnv*, const jchar*, jsize);    
    const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);     void        (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*); 
    jstring     (*NewStringUTF)(JNIEnv*, const char*);    
    const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);     void        (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*); 
    env->DeleteLocalRef(ref); 
    

    3.GetObjectField/GetObjectClass/GetObjectArrayElement

    jclass ref = env->GetObjectClass(robj); 
    env->DeleteLocalRef(ref);  
    

    4.GetByteArrayElements和GetStringUTFChars

    jbyte* array= (*env)->GetByteArrayElements(env,jarray,&isCopy); 
    (*env)->ReleaseByteArrayElements(env,jarray,array,0); 
    const char* input =(*env)->GetStringUTFChars(env,jinput, &isCopy); 
    (*env)->ReleaseStringUTFChars(env,jinput,input); 
    

    5.NewGlobalRef/DeleteGlobalRef
    jobject (NewGlobalRef)(JNIEnv, jobject);
    void (DeleteGlobalRef)(JNIEnv, jobject);
    例如,

    jobject ref= env->NewGlobalRef(customObj); 
    env->DeleteGlobalRef(customObj); 
    

    改完果然就没有再闪退了!

    相关文章

      网友评论

        本文标题:signal 11 (SIGSEGV)错误排查

        本文链接:https://www.haomeiwen.com/subject/rjqieqtx.html