JNI:Fatal signal 11 (SIGSEGV) at 0x00000008 (code=1)错误的一点认识


       最近做的一个东西需要jni去实现,对于一个我这样用惯了java,习惯了debug的人来说,用NDK,使用C/C++去编程是件很苦逼的事情,但是最苦逼的事情在于内存错误发生后如何排查,尤其是 Fatal signal 11 (SIGSEGV)这个错误尤其恼人,报出来之后程序就会崩溃,定位还不好定位,刚开始发生这样的错误时候,只能去到处加log,到处屏蔽代码去找问题发生的地方,效率比较低,并且很难找到问题真正出在哪,后来慢慢找到一些方法,可以相对比较快的定位到问题源头,一般情况下能相对容易的发现问题到底出在哪。下面简单的说说:

1:首先在logcat中加入debug(方法如图所示):


2:在运行后报错中会在debug中找到类似这样的一串错误



看到这个长长的错误,不要慌,我们就要拿着这个错误去分析:
首先,从这个长长的串中找到有用的信息
10-28 12:39:17.779: I/DEBUG(7749): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
10-28 12:39:17.779: I/DEBUG(7749):  r0 00000027  r1 deadbaad  r2 a0000000  r3 00000000
10-28 12:39:17.779: I/DEBUG(7749):  r4 00000001  r5 00000000  r6 44bc8c10  r7 44984e64
10-28 12:39:17.779: I/DEBUG(7749):  r8 44bc8b70  r9 44984e54  10 44984e3c  fp 800a5368
10-28 12:39:17.779: I/DEBUG(7749):  ip afd46668  sp 44bc8ae0  lr afd191d9  pc afd15ca4  cpsr 60000030
10-28 12:39:17.779: I/DEBUG(7749):  d0  646f423262287964  d1  6f42796f72747365
10-28 12:39:17.779: I/DEBUG(7749):  d2  646e412f65737062  d3  6850656e69676e32
10-28 12:39:17.779: I/DEBUG(7749):  d4  786f427363697379  d5  736e657478454432
10-28 12:39:17.779: I/DEBUG(7749):  d6  2f696e6a2f6e6f69  d7  79442f4432786f42
10-28 12:39:17.779: I/DEBUG(7749):  d8  42ce94f34e6e6b28  d9  3c8888893c888888
10-28 12:39:17.779: I/DEBUG(7749):  d10 c26f7c303f800000  d11 3fed9bafc26f7e0e
10-28 12:39:17.779: I/DEBUG(7749):  d12 0000000000000000  d13 0000000000000000
10-28 12:39:17.779: I/DEBUG(7749):  d14 0000000000000000  d15 0000000000000000
10-28 12:39:17.779: I/DEBUG(7749):  d16 3ef18d523ae9735c  d17 3fca68bfcfa2d635
10-28 12:39:17.779: I/DEBUG(7749):  d18 bf29fd09783e4216  d19 3ec6cd878c3b46a7
10-28 12:39:17.779: I/DEBUG(7749):  d20 3f826164f3f641b5  d21 3f5e8ec8e86d933e
10-28 12:39:17.779: I/DEBUG(7749):  d22 3e3782e7e0000000  d23 3e33401660000000
10-28 12:39:17.779: I/DEBUG(7749):  d24 3fca99a880000000  d25 bfca99a880000000
10-28 12:39:17.779: I/DEBUG(7749):  d26 be3ff77520000000  d27 3ef99342e0ee5069
10-28 12:39:17.779: I/DEBUG(7749):  d28 bfa2b4442c6a6c2f  d29 0000000000000000
10-28 12:39:17.779: I/DEBUG(7749):  d30 0000000000000000  d31 0000000000000000
10-28 12:39:17.779: I/DEBUG(7749):  scr 80000012
10-28 12:39:17.829: I/DEBUG(7749):          #00  pc 00015ca4  /system/lib/libc.so
10-28 12:39:17.829: I/DEBUG(7749):          #01  pc 0001c92c  /system/lib/libc.so

主要看红色加粗的地方(#打头的部分),这个表明了错误发生的原因和地方,因此问题分析从这个入手,一般情况下这个红色加粗部分有两种情况,一种情况就如上边的错误一样,报错都来在系统的so包,并且没有进一步详细的信息,这种情况下,问题可能出现的都比较弱智,一般主要去分析下jni入口函数,反调,数组是否越界,使用已经delete的资源等这些常规错误,稍微注意下可能就能找到源头,也可能问题非常棘手,要拼人品了哈。
第二种报错可能是类似与这样:
#00  pc 00011784  /system/lib/libc.so (pthread_attr_init)
#01  pc 000de128  /data/data/com.test.android.Test/lib/libDemo.so (_ZN6Demo6Test4InitEv)
#02  pc 000def90  /data/data/com.test.android.Test/lib/libDemo.so (_ZN6Demo16TestDemo4InitESsiiil)

可以看到错误直接报道咱们自己的so包,并且Test4Init能看到是Test类下的init方法,越上边是问题的越根源,这样我们就可以按图索骥,从Test的init方法里去仔细排查错误的原因,可以大大减少排查耗费的时间。

接下来比较高深的是通过汇编方式找具体的错误,目前还没用到,定位到方法基本可以解决问题,大家有兴趣的可以看下后边给出的参考文章。

目前在最近的工作中通过这一方法基本可以较快的找到问题的发生地方,比之前各种log和各种屏代码效率高了很多,如果大家还有更好的办法希望留言讨论一下。

参考文章:http://blog.youkuaiyun.com/helldevil/article/details/6682211

引用\[1\]:--------- beginning of crash C000A02 03-06 05:06:11.503 506 506 F libc : Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x72a3d4d000 in tid 506 (secure_element@), pid 506 (secure_element@) 。 引用\[2\]:结论:出现SIGSEGV,是进程执行了一个无效的内存引用。 如何分析:内存错误发生后如何排查,尤其是 Fatal signal 11 (SIGSEGV)这个错误,报出来之后程序就会崩溃,定位还不好定位,如何定位到所出问题的函数或者代码行?分析 crash 的堆栈信息,通过地址定位源文件中出错的函数或具体行数(addr2line) 。 引用\[3\]:好的查问题,发现是C++的底层文件报出的错误JNI层面的错误信息不太具体,只有靠打印信息一步步查看问题,最后定位是pthread_mutex_init(H264datalock, NULL)互斥量初始化找不到地址,再看互斥量定义:pthread_mutex_t *H264datalock,难道是指针没有初始化造成的,但是此程序在Android4.4下跑了很久了,从没有出现过这个问题啊!抱着怀疑的态度,试一试,互斥量定义改为pthread_mutex_t H264datalock,不用指针,初始化则改为pthread_mutex_init(&H264datalock, NULL),好了,程序又顺利运行了。 问题: fault addr是什么意思? 回答: fault addr是指在发生错误时,导致程序崩溃的内存地址。在这个例子中,错误是由于执行了一个无效的内存引用导致的,而fault addr则指示了具体的内存地址0x72a3d4d000。\[1\] #### 引用[.reference_title] - *1* *2* [Fatal signal 11 (SIGSEGV), code 2(SEGV_ACCERR), fault addr 解决方法](https://blog.youkuaiyun.com/Haomione/article/details/129737159)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Android5.0后出现的新错误fatal error 11 fault addr](https://blog.youkuaiyun.com/allencheung2010/article/details/49329203)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值