這周和同事一起解了個tombstone的bug, 記錄下分析的過程,免得以后又忘記。。。
1>log的分析
pid: 122, tid: 14745, name: Binder_2 ?>>> /system/bin/mediaserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000058
eax 00000000 ?ebx 41bbf784 ?ecx 00000000 ?edx 00000009
esi 450578f0 ?edi 40378054
xcs 00000073 ?xds 0000007b ?xes 0000007b ?xfs 00000000 ?xss 0000007b
eip 4088a5c2 ?ebp 45e15cb8 ?esp 45e15ca0 ?flags 00010297
backtrace:
#00 ?pc 000085c2 ?/system/lib/libcameraservice.so (android::CameraHardwareInterface::__set_buffer_count(preview_stream_ops*, int)+34)
#01 ?pc 0003b6fa ?/system/lib/hw/camera.XXXX.so (android::PreviewThread::allocateGfxPreviewBuffers(int)+154)
#02 ?pc 0003ce83 ?/system/lib/hw/camera.XXXX.so (android::PreviewThread::threadLoop()+1203)
#03 ?pc 0001a2bc ?/system/lib/libutils.so (android::Thread::_threadLoop(void*)+556)
#04 ?pc 0000dda8 ?/system/lib/libc.so (__thread_entry+248)
#05 ?pc 0001b031 ?/system/lib/libc.so
#06 ?pc 00001f2c ?/system/lib/libc.so
從log可以看出, 進程遇到了一個空指針,出錯地址為00000058. ?一般產生tombstone的問題可能是訪問已經被釋放的數據,也可能是結構體中的某個函數指針為空。從CPU的寄存器可以看出通用寄存器的eax里的數據為0.
2>對發生問題的庫文件進行反匯編,來找到出錯的代碼行。
00008b40 <_zn7android23camerahardwareinterface18__set_buffer_countep18preview_stream_opsi>:
8b40: ? ? ? 55 ? ? ? ? ? ? ? ? ? ? ?push ? %ebp
8b41: ? ? ? 89 e5 ? ? ? ? ? ? ? ? ? mov ? ?%esp,%ebp
8b43: ? ? ? 8d 64 24 e8 ? ? ? ? ? ? lea ? ?-0x18(%esp),%esp
8b47: ? ? ? 8b 45 08 ? ? ? ? ? ? ? ?mov ? ?0x8(%ebp),%eax
8b4a: ? ? ? 8b 55 0c ? ? ? ? ? ? ? ?mov ? ?0xc(%ebp),%edx
8b4d: ? ? ? 8b 40 2c ? ? ? ? ? ? ? ?mov ? ?0x2c(%eax),%eax
8b50: ? ? ? 8b 40 0c ? ? ? ? ? ? ? ?mov ? ?0xc(%eax),%eax
8b53: ? ? ? 89 54 24 08 ? ? ? ? ? ? mov ? ?%edx,0x8(%esp)
8b57: ? ? ? c7 44 24 04 04 00 00 ? ?movl ? $0x4,0x4(%esp)
8b5e: ? ? ? 00
8b5f: ? ? ? 89 04 24 ? ? ? ? ? ? ? ?mov ? ?%eax,(%esp)
8b62: ? ? ? ff 50 58 ? ? ? ? ? ? ? ?call ? *0x58(%eax) ? ? ? ? ? <==出錯的地方
8b65: ? ? ? c9 ? ? ? ? ? ? ? ? ? ? ?leave
8b66: ? ? ? c3 ? ? ? ? ? ? ? ? ? ? ?ret
8b67: ? ? ? 89 f6 ? ? ? ? ? ? ? ? ? mov ? ?%esi,%esi
8b69: ? ? ? 8d bc 27 00 00 00 00 ? ?lea ? ?0x0(%edi,%eiz,1),%edi
在從匯編代碼反推到對應的C/C++代碼。
3> 找到出錯的代碼后,手動來設置相應的數據結構為空來驗證能否產生相同的出錯信息 4> 最后就是從tombstone的log文件去找線程間的同步問題。。。這里是最糾結的地方,得多看代碼找可能的同步問題,然后加鎖同步。。。