目录
一、Tombstone定义
墓碑。当一个动态库(native 程序)开始执行时,系统会注册一些连接到 debuggerd 的 signal handlers,当系统 crash 的时候,会保存一个 tombstone 文件到/data/tombstones目录下(Logcat中也会有相应的信息),文件的确就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。
对于问题定位非常有用。
二、快速解决
Tomestone样例(已隐去敏感信息):
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'xxx'
Revision: '0'
ABI: 'arm64'
Timestamp: 2023-01-29 02:27:42.367624270+0800
Process uptime: 19s
Cmdline: /vendor/bin/android.hardware.automotive.evs@1.0-ais
pid: 504, tid: 504, name: evs@1.0-ais >>> /vendor/bin/android.hardware.automotive.evs@1.0-ais <<<
uid: 1000
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x702f3421d4
x0 00000000ffffffea x1 0000000000000080 x2 0000007fd0ccb200 x3 0000000000000080
x4 000000000000000c x5 00000000fffffff8 x6 0000000000000017 x7 0000000000000438
x8 000000702f33b010 x9 00000000000071c4 x10 0000000000000780 x11 0000000000000002
x12 0000007fd0ccb5e8 x13 00000070abb2af8c x14 0000007fd0ccb548 x15 0000007fd0ccb438
x16 00000070ab8642b0 x17 00000070ab8619d4 x18 0000007138dec000 x19 0000007fd0ccb200
x20 000000702f33b000 x21 0000007137ecc000 x22 000000702f340c34 x23 00000000000001fb
x24 b400007137aa1560 x25 b400007137aa87b0 x26 0000000000000000 x27 0000007137ecc000
x28 0000000000000000 x29 0000007fd0ccb190
lr 00000070ab7f8ddc sp 0000007fd0cca680 pc 00000070ab861bf4 pst 0000000060000000
backtrace:
#00 pc 0000000000002bf4 /vendor/lib64/libqdMetaData.so (getMetaDataVa+544) (BuildId: 5f8f611fe24daad279605726e2140611)
#01 pc 0000000000006dd8 /vendor/lib64/libgrallocutils.so (gralloc::GetCustomDimensions(private_handle_t*, int*, int*)+76) (BuildId: 95f208c6056517672d1fa2c0ce46c9a4)
#02 pc 000000000000d870 /vendor/lib64/hw/android.hardware.graphics.mapper@4.0-impl-qti-display.so (vendor::qti::hardware::display::mapperextensions::V1_1::implementation::QtiMapperExtensions::getCustomDimensions(void*, std::__1::function<void (vendor::qti::hardware::display::mapperextensions::V1_0::Error, int, int)>)+104) (BuildId: 496c1d7446fe4c37158d156b97488608)
#03 pc 0000000000017024 /vendor/lib64/vendor.qti.hardware.display.mapperextensions@1.1.so (vendor::qti::hardware::display::mapperextensions::V1_1::BsQtiMapperExtensions::getCustomDimensions(void*, std::__1::function<void (vendor::qti::hardware::display::mapperextensions::V1_0::Error, int, int)>)+152) (BuildId: 86b03cacb633046f5001ffbd4d19c6a6)
#04 pc 00000000000104ec /vendor/lib64/egl/eglSubDriverAndroid.so (BuildId: 5b97660bec7ac290203b0cbf9d44710a)
#05 pc 00000000000122fc /vendor/lib64/egl/eglSubDriverAndroid.so (BuildId: 5b97660bec7ac290203b0cbf9d44710a)
#06 pc 0000000000013fb4 /vendor/lib64/egl/eglSubDriverAndroid.so (BuildId: 5b97660bec7ac290203b0cbf9d44710a)
#07 pc 00000000002bebd0 /vendor/lib64/egl/libGLESv2_adreno.so (BuildId: b5a32c58a407e9d5153c7ed114659e3f)
#08 pc 00000000001c3fd8 /vendor/lib64/egl/libGLESv2_adreno.so (BuildId: b5a32c58a407e9d5153c7ed114659e3f)
#09 pc 00000000001c5870 /vendor/lib64/egl/libGLESv2_adreno.so (BuildId: b5a32c58a407e9d5153c7ed114659e3f)
#10 pc 00000000002077d4 /vendor/lib64/egl/libGLESv2_adreno.so (BuildId: b5a32c58a407e9d5153c7ed114659e3f)
#11 pc 0000000000011258 /vendor/bin/android.hardware.automotive.evs@1.0-ais (GlWrapper::renderImageToScreen()+80) (BuildId: 22b5c23192874a857be557ff2bacc8e8)
#12 pc 0000000000022638 /vendor/bin/android.hardware.automotive.evs@1.0-ais (android::hardware::automotive::evs::V1_0::implementation::EvsGlDisplay::returnTargetBufferForDisplay(android::hardware::automotive::evs::V1_0::BufferDesc const&)+204) (BuildId: 22b5c23192874a857be557ff2bacc8e8)
#13 pc 000000000002d598 /apex/com.android.vndk.v31/lib64/android.hardware.automotive.evs@1.0.so (android::hardware::automotive::evs::V1_0::BnHwEvsDisplay::_hidl_returnTargetBufferForDisplay(android::hidl::base::V1_0::BnHwBase*, android::hardware::Parcel const&, android::hardware::Parcel*, std::__1::function<void (android::hardware::Parcel&)>)+220) (BuildId: e989defcc1a8408c61f50ee43d898657)
#14 pc 000000000002da30 /apex/com.android.vndk.v31/lib64/android.hardware.automotive.evs@1.0.so (android::hardware::automotive::evs::V1_0::BnHwEvsDisplay::onTransact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+404) (BuildId: e989defcc1a8408c61f50ee43d898657)
#15 pc 00000000000768a4 /apex/com.android.vndk.v31/lib64/libhidlbase.so (android::hardware::BHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+92) (BuildId: 1c806a0c7106677e8355f6be1abbdb9b)
#16 pc 0000000000074eb8 /apex/com.android.vndk.v31/lib64/libhidlbase.so (android::hardware::IPCThreadState::getAndExecuteCommand()+1104) (BuildId: 1c806a0c7106677e8355f6be1abbdb9b)
#17 pc 0000000000074988 /apex/com.android.vndk.v31/lib64/libhidlbase.so (android::hardware::IPCThreadState::joinThreadPool(bool)+96) (BuildId: 1c806a0c7106677e8355f6be1abbdb9b)
#18 pc 00000000000121d0 /vendor/bin/android.hardware.automotive.evs@1.0-ais (main+576) (BuildId: 22b5c23192874a857be557ff2bacc8e8)
#19 pc 00000000000822d4 /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+96) (BuildId: a01cf07b6a9f32a66547d7774501375f)
...
...
...
如何去看?
首先,出错的动态库为:
Cmdline: /vendor/bin/android.hardware.automotive.evs@1.0-ais
然后,看backtrace,顾名思义,出错栈。从上到下就是调用栈的逆序,可以看到赘述到evs@1.0-ais这个动态库的GlWrapper::renderImageToScreen()函数:
#11 pc 0000000000011258 /vendor/bin/android.hardware.automotive.evs@1.0-ais (GlWrapper::renderImageToScreen()+80) (BuildId: 22b5c23192874a857be557ff2bacc8e8)
范围很小了吧,但仍不够,我们想定位到具体哪一行,后面+80并不是行数,我们只关注pc后面的地址0000000000011258。那么就开始使用addr2line工具。addr2line工具在linux是就有,所以在真机上把/vendor/bin/android.hardware.automotive.evs@1.0-ais拉出来:
adb pull /vendor/bin/android.hardware.automotive.evs@1.0-ais
然后放到linux系统上,执行:
addr2line 0000000000011258 -e android.hardware.automotive.evs@1.0-ais -f -C -s
如果出现:
GlWrapper::renderImageToScreen()
??:?
说明编译时符号表被优化掉了,那么重新编译这个动态库,然后再out目录下找生成的带符号表的文件,路径类似:
路径类似于:out/target/product/xxx/symbols/vendor/bin
关键就是symbols这个文件夹,里面存放的是未被优化符号表的文件。
在这下面执行同样的命令:
addr2line 0000000000011258 -e android.hardware.automotive.evs@1.0-ais -f -C -s
获得:
GlWrapper::renderImageToScreen()
GlWrapper.cpp:441
好了,定位到了,就是GlWrapper::renderImageToScreen()这个接口,代码是第441行。
学会了吗?
三、注意事项
如果系统里是被优化掉的动态库,你需要编译重新生成,那么请保证编译系统里那个库的代码和本地的代码基本一致,这样代码行数才能对应。好像是废话,哈哈。