2012-09-07 36 views
7

我想調試我的自定義Linux發行版上的pthreads,但我錯過了一些東西。我的主機是Ubuntu 12.04,我的目標是使用crosstool-NG交叉編譯器工具集構建的i486定製嵌入式Linux,其餘操作系統由Buildroot製作。我需要調試pthreads?

我將列出事實:

  • 我可以運行我的目標多線程應用程序

  • Google Breakpad失敗,當我運行在目標上的多線程應用程序創建一個崩潰報告。當我在主機上運行完全相同的應用程序和完全相同的Breakpad庫時,它將會成功。

  • GDB無法在我的目標上調試多線程應用程序。

例如,

$./gdb -n -ex "thread apply all backtrace" ./a.out --pid 716 

dlopen failed on 'libthread_db.so.1' - /lib/libthread_db.so.1: undefined symbol: ps_lgetfpregs 
GDB will not be able to debug pthreads. 
GNU gdb 6.8 

我不認爲ps_lgetfpregs是一個問題,因爲this

  • 我的crosstool build創建了libthread_db.so文件,並將其放在目標上。

  • 我的crosstool build爲我的目標創建了gdb,所以它應該與我在目標上運行的相同庫鏈接。

  • 如果我在我的主機上運行gdb,對我的測試應用程序,我得到每個運行線程的回溯。

我懷疑Breakpad的問題與GDB的問題有關,但我無法證實這一點。唯一的共同點是缺乏多線程調試。

我的主機和目標之間有一些至關重要的區別,它使我無法調試目標上的pthread。

有人知道它是什麼嗎?

編輯:

Denys Dmytriyenko從TI說:

通常情況下,GDB不是很挑剔,你可以混合和匹配不同版本 GDB和gdbserver的的。但不幸的是,如果你需要 調試多線程應用程序,還有一些依賴於特定的API ...

例如,這是消息中的一個,如果你沒有 構建GDB您可能會看到正確的線程支持:

的dlopen失敗了「的libthread_db.so.1」 - /lib/libthread_db.so.1: 未定義的符號:ps_lgetfpregs GDB無法調試 並行線程。

請注意,該錯誤與我所得到的錯誤相同,但他沒有詳細介紹如何正確構建GDB。

GDB FAQ說:

(Q)GDB沒有看到除了在發生碰撞的任何一個線程;當我設置斷點時,SIGTRAP會殺死我的程序。 (A)這種情況經常發生在Linux上,尤其是嵌入式目標上。有兩種常見的 原因:

  • 您使用的glibc,並且您已經剝離libpthread.so.0 libpthread.so.0和的libthread_db.so.1

之間

  • 不匹配

    GDB本身確實不知道如何解碼由glibc維護的「線程控制塊」和被認爲是glibc私有實現細節的 。它使用 libthread_db.so.1(glibc的一部分)來幫助它這樣做。因此, libthread_db.so.1和libpthread.so.0必須在版本號和 編譯標誌中匹配。另外,libthread_db.so.1要求某些 非全局符號出現在libpthread.so.0中。

    解決方案:使用 strip --strip-debug libpthread.so.0而不是strip libpthread.so.0。

  • 我試過一個沒有剝離的libpthread.so.0,但沒有什麼區別。我將研究pthread和thread_db之間的任何不匹配。

    +0

    你是在同一時間玩弄火焰吃喝玩樂嗎?你當然不喜歡讓自己變得輕鬆自在。 –

    +0

    哈哈哈,是的。歡迎來到嵌入式Linux,這裏沒有任何東西是直接的,你必須知道一切(但從來沒有足夠的真正能力)。 –

    +0

    事實證明,使用-static選項構建gdb會取消-rdynamic選項,它會停止thread_db在靜態gdb中查找符號。因此錯誤「未定義符號:ps_lgetfpregs」 –

    回答

    2

    此:

    dlopen failed on 'libthread_db.so.1' - /lib/libthread_db.so.1: undefined symbol: ps_lgetfpregs 
    GDB will not be able to debug pthreads. 
    

    libthread_db.so.1庫無法找到符號ps_lgetfpregs在gdb。

    爲什麼?

    因爲我使用Crosstoolg-NG與「構建靜態本機gdb」選項構建gdb,並且這會將-static選項添加到gcc。

    本地gdb使用-rdynamic選項構建,並在ELF文件中使用所有符號填充.dynsym符號表,其中包含所有符號,甚至未使用的符號表。 libread_db使用此符號表從gdb中查找ps_lgetfpregs

    但是-static從ELF文件中剝離了.dynsym表。

    此時有兩種選擇:

    1. 如果你想調試線程不建立一個靜態的本地GDB。
    2. 建立一個靜態的GDB和靜態libthread_db所(未測試)

    編輯:

    順便說一句,這並不能解釋爲什麼Breakpad在無法調試上我的目標多線程應用程序。

    0

    只是一個雖然......要使用gdb調試器,您需要使用-g選項編譯您的代碼。例如,gcc -g -c * .c。