2013-07-13 64 views
1

當我的Android應用程序崩潰(或觸發斷言)時,我從來沒有得到超過四行的回溯。尋找類似的問題,我只找到一個或兩個地方提到這個問題,股票的迴應是:「確保它是一個調試版本」和「你可能有堆棧損壞」。我看到很多地方出現了許多撞車事故,車架外觀精確,沒有腐敗跡象。logcat中的不完整回溯

下面是'亞行logcat」按照調試版本的斷言失敗採取了典型的摘錄:

I/DEBUG ( 187):  d28 3f824fc6ced25306 d29 3fabdfebb8fe14dc 
I/DEBUG ( 187):  d30 fff0000000000000 d31 fffffffeffffffd2 
I/DEBUG ( 187):  scr 88000010 
I/DEBUG ( 187): 
I/DEBUG ( 187): backtrace: 
I/DEBUG ( 187):  #00 pc 00018516 /system/lib/libc.so 
I/DEBUG ( 187):  #01 pc 0000dc44 /system/lib/libc.so (abort+4) 
I/DEBUG ( 187):  #02 pc 0000168d /system/lib/liblog.so (__android_log_assert+88) 
I/DEBUG ( 187):  #03 pc 00170bcc /data/data/com.jsam.crag/lib/libmain.so (sim::TouchObserverController::HandleEvent(SDL_Event const&)+340) 
I/DEBUG ( 187): 
I/DEBUG ( 187): stack: 
I/DEBUG ( 187):   6f4be770 6f4be76c [stack:17025] 
I/DEBUG ( 187):   6f4be774 00000000 
I/DEBUG ( 187):   6f4be778 00000000 

正如你可以看到,大部分可用回溯的甚至不是在我自己的代碼。我正在開發版本的HTC One上使用開箱即用的操作系統,使用NDK的版本8e並針對android-10進行構建,儘管android-15也不例外。我使用的工具鏈V4.7中,gnustl_static STL和我的C++標誌是:

-std=c++11 -g -pthread -DPROFILE -D__STRICT_ANSI__ -DdSINGLE -Wall -Wextra -Wfatal-errors -fno-rtti -fno-exceptions 

我將如何去獲得更長的(最好是完整的)回溯?

回答

0

答案似乎是升級到Android 4.3。我的手機今天收到了一個更新(定製的HTC版本推出到開發人員版設備上),並且轉儲到系統日誌的回溯現在顯示出完整的堆棧。然而,正如@ user1034749所表明的那樣,抓住GDB是一個很好的選擇,並帶來許多額外的好處。

+0

更新至4.3似乎對我沒有任何幫助:/ –

+0

@kotlinski您是否運行相同/不同的設備等?你還看到只有四行? –

1

您可以用GDB對本地應用在Android上調試運行,見 Generate core dump in android

這可以給你,不只是堆棧跟蹤。

+0

謝謝。這在調試應用程序時非常有用,但如果在連接調試器之前崩潰了,我認爲logcat是我唯一的信息來源。 (如果Android應用程序拋出一個核心文件,我會很驚訝。) –

+0

在另一個主題中(現在找不到鏈接)有注意,如果您在運行控制檯應用程序核心轉儲工作的根設備上工作,如果使用模擬ulimit -c無限制。但是如果涉及核心轉儲的java代碼不起作用,這可能是因爲java運行時在某處停用了它。 – fghj

+0

謝謝。雖然我很確定我的手機都已解鎖,但只有其中一個手機具有此限制,但我會仔細查看。 –

1

調試器堆棧跟蹤機制使用異常展開機制來遍歷樹。這是使用gcc -funwind-tables參數啓用的。

gdb忽略這些並使用自己的機制,它依靠反彙編代碼來確定返回值在堆棧中的位置。這通常適用於gcc生成的代碼,但可能會感到困惑。有時gdb或debuggerd將能夠解碼另一個不能的堆棧跟蹤。

(編輯:多個音符)

的基本問題是,編譯器被配置爲生成不使用幀指針代碼。調用者將返回地址放在LR寄存器中,被調用函數在完成時分支給它。 LR是一個通用寄存器,因此通常將其傳送到堆棧並在返回之前進行恢復。遍歷堆棧的代碼需要判斷是否溢出,如果存在,堆棧中可能會找到堆棧的位置。

由於某種原因,debuggerd似乎並不認爲它可以遍歷更遠的堆棧。原因之一是沒有展開信息。

+0

感謝您的信息。我曾嘗試添加-funwind-tables,但沒有發現任何明顯的差異。 debuggerd(或者任何正在產生logcat的信息)似乎絕對沒有問題象徵着前四行的堆棧;它始終打印出四行準確的信息,不再有更多。它看起來像在某個地方的所有世界,信息是故意封頂 - 可能節省記錄器輸出。 –

+0

(我在答案中增加了一些細節。)調試器中有一個上限,但它被設置爲32幀。嘗試刪除'-fno-exceptions',或者確保它在'-funwind-tables'之前指定。我想知道是否無例外情況會禁用表格生成。 – fadden

+0

刪除'-fno-exceptions'並添加'-funwind-table'似乎沒有什麼區別。我注意到從'ndk-gdb'發佈'bt'現在給出了不好的結果,例如'#3 0x400c3690在? ()'。另外,我在Nexus One上(使用CyanogenMod)創建了同樣的崩潰,並得到了一個完整的,但是損壞的函數名稱堆棧,如:_ZN3sim23TouchObserverController11HandleEventERK9SDL_Event。所以我現在想知道是操作系統還是有問題的設備。 –