2011-02-24 64 views
8

正如我已經注意到了,logcat的回報總是34線的崩潰日誌,就像這樣:如何從android獲得更長的堆棧轉儲(墓碑)?

4cf7c700 401c0000 
4cf7c704 48463ff0 
4cf7c708 44d11f7c 
4cf7c70c afd0cd89 
4cf7c710 00000000 
4cf7c714 82ab29dc libmyproject.so 
4cf7c718 00000000 
4cf7c71c 4cf7c73c 
4cf7c720 836c44f0 libmyproject.so 
4cf7c724 82f3a414 libmyproject.so 
4cf7c728 4cf7c768 
4cf7c72c 0000008d 
4cf7c730 007ea0a8 [heap] 
4cf7c734 00270100 [heap] 
4cf7c738 e3a07077 
4cf7c73c ef900077 
4cf7c740 00000000 
4cf7c744 4cf7c774 
4cf7c748 836c44f0 libmyproject.so 
4cf7c74c 00000000 
4cf7c750 836c44f0 libmyproject.so 
4cf7c754 82f63768 libmyproject.so 
4cf7c758 00000000 
4cf7c75c 4cf7c7e4 
4cf7c760 00000000 
4cf7c764 00000001 
4cf7c768 00000000 
4cf7c76c 0badc0de 
4cf7c770 fffffff8 
4cf7c774 00000000 
4cf7c778 00000168 
4cf7c77c 00000009 
4cf7c780 00000200 
4cf7c784 00000000 

但是我知道,堆也被保存到/date/tombstones/tombstone_0[0-9]。在那裏我可以找到許多其他堆棧(我不完全明白它們來自哪裏),其中一些堆棧比前述堆棧長兩倍。

如何從我的應用程序崩潰得到如此長的堆棧轉儲?

回答

10

我建議調試在墓碑文件中找到的堆棧跟蹤,如下面的例子。

例子:

#00 pc 00010a20 /system/lib/libc.so 
#01 pc 0000b332 /system/lib/libc.so 
#02 pc 0000ca62 /system/lib/bluez-plugin/audio.so 
#03 pc 0000d1ce /system/lib/bluez-plugin/audio.so 
#04 pc 0000e0ba /system/lib/bluez-plugin/audio.so 

您可以使用下面的命令來知道函數名,文件名和行沒有。

$(android-root)prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/addr2line -f -e /out/product/xxx/symbols/system/<SO filename> <PC address> 

實施例:

​​
18

在機器人的碰撞處理程序,這是所謂debuggerd,只寫堆棧入日誌的部分的,但完整的堆棧寫入墓碑文件。這在system/core/debuggerd/debuggerd.c中是硬編碼的。

查看調用_LOG()的例程debug_stack_and_code()。 _LOG的第二個參數控制着東西是否只進入邏輯刪除或記錄和邏輯刪除。

如果您看到(sp_depth>2||only_in_tombstone),您可以將2更改爲其他內容以獲取日誌中報告的更深的堆棧幀。這假設您可以重新編譯debuggerd並將其替換到您的系統上。如果不是的話,你會被困在檢查墓碑文件本身以獲得更長的堆棧轉儲。

轉儲是在Linux下程序崩潰時由debuggerd創建的。發生這種情況時,內核會向死掉的程序發送一個信號。該信號被安裝在每個原生Android應用程序中的特殊信號處理程序捕獲。由仿生C庫提供。信號處理程序會聯繫debuggerd(通過命名管道),然後使用ptrace連接到死亡程序以讀取寄存器和內存以生成邏輯刪除和日誌條目。