2017-10-21 163 views
1

我有一個android應用程序崩潰在本地代碼在某些情況下,我不能再現。 我在使用visual studio構建的可執行文件的崩潰調查方面擁有豐富的經驗,並且包含適當的PDB文件。不幸的是,我在gcc中沒有這樣的經驗,但我理解所需的概念。崩潰調查,從.so文件恢復符號

我沒有崩潰轉儲,只有調用堆棧(由谷歌播放控制檯報告)。它從java代碼開始,然後轉到.so庫的公共符號,然後在本地代碼中也有一個調用堆棧。當然,符號是不可見的,因爲它是一個發佈版本,其中剝離了私有符號。

我使用標準的NDK構建腳本。在輸出發佈版本,我有以下:

  • 的發行版本.so文件,700KB〜
  • 在中間(臨時)文件目錄:
    • 。所以使用相同的文件名,8.4MB
    • OBJ文件目錄,各種的.o和.od文件

所以,我需要指導如何找出符號。位於中間目錄中的.so文件比釋放目錄中具有相同名稱的文件大得多。這些文件在小文件的末尾幾乎是相同的。 看來,較大的文件實際上是相同的,並且在最後附加了調試信息。用HEX查看器打開它並搜索一些符號名稱(C++ - 裝飾函數名稱) - 它肯定包含它們。

我試圖在較大的文件上使用nm -gC工具。它確實顯示了一些符號,但這是不夠的:它只包含公共符號(即模塊故意導出的JNI方法),以及構建過程中使用的std庫中的大量內容(標準C/C++函數,pthread stuff,一些東西與例外和RTTI有關)。但是沒有內部函數名稱,這些名稱肯定存在於文件中。

所以,我錯過了什麼?是否有應該指定到nm的選項?或者應該使用其他工具? 在此先感謝。

+0

最常與GCC一起使用的「標準」GNU調試器是一個調用GDB。我建議你簡單地搜索'gdb從文件讀取符號',你應該能夠快速得到你的答案。您可以通過簡單地從可用的調試版本加載符號來調試版本構建。 –

回答

1

通常,addr2line是此工作的工具。它將查看調試信息並報告行號和功能行。有一些選項可以提高輸出(處理內聯函數,解除符號)。

但是你需要補償ASLR(地址空間佈局隨機化)。我從來沒有見過谷歌崩潰報告,所以我不知道它是否提供了相對於共享對象的加載地址的地址,或者是否有其他方法來恢復相對地址。絕對地址在這種情況下非常難以使用。

+0

謝謝,夥計。這有幫助。 – valdo