Ndk c++层 crash问题分析

首先你要从设备上拿到墓碑文件:tombstone,这里面会记录系统崩溃时的信息。位置在/data/tombstones目录下(Logcat中也会有相应的信息),文件的确就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等,里面会有多个tombstone 可以用ll命令来查看时间来区分找到你要找的那个时间的crash。以我正在处理的问题为例看一下tombstone的样子:


Build fingerprint: ‘Android/rk3399_all/rk3399_all:7.1.2/NHG47K/crh12271002:eng/test-keys’
Revision: ‘0’
ABI: ‘arm’
pid: 6657, tid: 6670, name: Binder:6657_2 >>> com.dcm360.robot <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
r0 00000000 r1 11535ca6 r2 f4d00500 r3 00000080
r4 f30aef55 r5 e9005460 r6 85973e40 r7 f41e4008
r8 00000000 r9 00000010 sl f0f966a0 fp 00000000
ip f41df948 sp f0f96688 lr f41bec3b pc f42ac8d2 cpsr 600f0030
d0 3239393737383632 d1 2070616548797272
d2 0000003c00000069 d3 0000000000000070
d4 0000000000000020 d5 0000000000000008
d6 00000000f1096b10 d7 00000000f1096b30
d8 0000278900001a01 d9 0000000000000000
d10 0000000000000000 d11 0000000000000000
d12 0000000000000000 d13 0000000000000000
d14 0000000000000000 d15 0000000000000000
d16 2e74736973726570 d17 2e6761742e676f6c
d18 000000000001c5c8 d19 00000000000166f0
d20 0000000000000000 d21 0000000000000000
d22 656d72612c613776 d23 0000000000000000
d24 0000003f0000003f d25 0000000000000000
d26 0000000000000000 d27 0000000000000000
d28 0000000000000000 d29 0000000000000000
d30 0000000000000000 d31 00000000003a6151
scr 80000093

backtrace:
#00 pc 000b28d2 /system/lib/libandroid_runtime.so (_ZN16JNICameraContext11copyAndPostEP7_JNIEnvRKN7android2spINS2_7IMemoryEEEi+45)
#01 pc 000b2cb3 /system/lib/libandroid_runtime.so (_ZN16JNICameraContext8postDataEiRKN7android2spINS0_7IMemoryEEEP21camera_frame_metadata+118)
#02 pc 0002437b /system/lib/libcamera_client.so (_ZN7android6Camera12dataCallbackEiRKNS_2spINS_7IMemoryEEEP21camera_frame_metadata+66)
#03 pc 00029847 /system/lib/libcamera_client.so (_ZN7android8hardware14BnCameraClient10onTransactEjRKNS_6ParcelEPS2_j+370)
#04 pc 000359f3 /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+70)
#05 pc 0003d1eb /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+702)
#06 pc 0003ce37 /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+114)
#07 pc 0003d34b /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+46)
#08 pc 0004f8f5 /system/lib/libbinder.so
#09 pc 0000e345 /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
#10 pc 0006675d /system/lib/libandroid_runtime.so (_ZN7android14AndroidRuntime15javaThreadShellEPv+80)
#11 pc 000470c3 /system/lib/libc.so (_ZL15__pthread_startPv+22)
#12 pc 00019e3d /system/lib/libc.so (__start_thread+6)

stack:
f0f96648 00000000
f0f9664c 00000000
f0f96650 00010001
f0f96654 00000000
f0f96658 f0f96680
f0f9665c 00000000
f0f96660 11535ca6
f0f96664 f30aef55 /system/lib/libbinder.so (_ZNK7android8BpMemory9getMemoryEPiPj)
f0f96668 e9005460 [anon:libc_malloc]
f0f9666c 85973e40 [anon:libc_malloc]
f0f96670 f41e4008 [anon:.bss]
f0f96674 00000000
f0f96678 00000010
f0f9667c f0f966a0
f0f96680 00000000
f0f96684 f42ac8d1 /system/lib/libandroid_runtime.so (_ZN16JNICameraContext11copyAndPostEP7_JNIEnvRKN7android2spINS2_7IMemoryEEEi+44)
#00 f0f96688 00000000
f0f9668c f30c2e01 /system/lib/libbinder.so (_ZN7android12ProcessState23getStrongProxyForHandleEi+104)
f0f96690 f4932180 [anon:libc_malloc]
f0f96694 e66ef92c [anon:libc_malloc]
f0f96698 00000000
f0f9669c 00000000
f0f966a0 00000000
f0f966a4 11535ca6
f0f966a8 11535ca6
f0f966ac 85973e40 [anon:libc_malloc]
f0f966b0 f41e4008 [anon:.bss]
f0f966b4 f0f966e0
f0f966b8 e9005460 [anon:libc_malloc]
f0f966bc 00000000
f0f966c0 00000010
f0f966c4 f0f96730
… …
信号名 值 默认动作 发出原因
SIGQUIT 3 终止进程 键盘的退出键被按下,虚拟机下用来打印堆栈
SIGILL 4 终止进程 非法指令
SIGABRT 6 终止进程 由abort(3)发出的终止指令,用户无法终止
SIGSEGV 11 终止进程 无效的内存引用
SIGBUS 7 终止进程 总线错误(错误的内存访问)

SIGBUS与SIGSEGV的区别
SIGBUS(Bus error)意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。比如int型要4字节对齐,short型的2字节对齐。例如:short array[16];int * p = (int *)&array[1];*p = 1;SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对应该地址。例如:int pi= (int)0x00001111;*pi = 17

原文链接:https://blog.csdn.net/qq_37635373/article/details/125354343
拿到这个文件了,可以看到上面记录的是crash .so 的地址,有两种方式处理,但也要分情况选择,如果你有设备来测试,并且知道如何去复现这个crash 那你可以用ndk-stack来直接将crash翻译成指向代码的容易理解的log,现在是指向地址的tomstone,其实这种也就不需要tomstone了,前提是你要判断出来,crash时因为c++ native层的,我就不具体解释ndk-stack怎么使用了,如果后面观众老爷留言有需要我再补吧,也是ndk带的一个工具。而当你不知道怎么复现,或者不是必现的情况,设备也不在身边,不方便直接处理。那你可以根据tomstone里面的地址,用addr2line 对tomstone 记录的so文件的地址进行转换成能看懂的代码出处,从而找到问题所在。下面是实操,先弄到so文件,这个so文件,可能是你自己项目里面的so文件,那它的地址你是知道的,也可能是系统的so文件,在设备上,以我这次为例,就需要adb pull 去把so文件拉下到电脑上,
在这里插入图片描述我要找到so在/system/lib/下面。

然后用命令去拿对映射对应的代码:
/home/zhouzhihao/Android/Sdk/ndk/21.4.7075529/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-addr2line -C -f -e libc.so 000470c3 00019e3d
addr2line 是ndk里面的一个工具 后面的地址对应就是tomstone上面记录的地址。

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
以上就是从/system/lib/下面不同的so文件对应的代码位置。

猜你喜欢

转载自blog.csdn.net/u012553125/article/details/131374709