gdbserver 移植與多執行緒除錯

KingsLanding發表於2014-03-23

  在嵌入式linux平臺使用gdb除錯進行遠端除錯需要安裝gdbserver,gdbserver工作在目標板上,通過串列埠或者網線與主機上的gdb互聯實現遠端除錯。

  Gdbserver需要根據不同的嵌入式平臺來編譯生成,首先到http://ftp.gnu.org/gnu/gdb/下載合適的版本。然後在本地進行編譯。在Unbuntu下編譯gdb需要安裝ncurses 庫,在redhat上通過yum install “Development tools” 安裝依賴就可以了。

  首先編譯主機端gdb,編譯過程如下:

  解壓原始碼包:

  $> tar xzvf gdb 7.3.1.tar.gz

  進入目錄:

  $>cd gdb-7.3.1

  生成makefile檔案:

  $>./configure --target=arm-linux --prefix=/mygdb7.3.1

或者,如果是mips平臺

  $>./configure --target=mips-linux --prefix=/mygdb7.3.1

  $> make

  $> make install

  執行結束之後你就會在mygdb7.3.1資料夾下bin目錄找到arm-linux-gdb 或者 mips-linux-gdb 可執行檔案。

  注意:執行 configure 步驟的時候目錄一定要選對,否則編譯會失敗,各種找到不到依賴!

  此外,由於這是生成在Linux主機上除錯的可執行檔案,因此不必使用交叉編譯環境,換句話說在編譯生成gdbserver的時候需要使用交叉編譯器。

  接下來編譯執行在目標板上的gdbserver。

  首先進入gdbserver目錄(在gdb7.3.1目錄中):

  $>cd gdb gdbserver

  生成makefile檔案,這一步需要指定交叉編譯器的位置,假設你交叉編譯的位置在xx/yy目錄下:

  $>CC=xx/yy/arm-linux-gcc ./configure  --target=arm-linux  --host=arm-linux 

  生成gdbserver

  $> make

  這裡沒有指定—prefix引數,因此生成的gdbserver就位於 gdb7.3.1/gdb/gdbserver目錄下。

  現在可以將gdbserver移植到目標板中了,方法有很多,就看你的環境了,可以使用nfs,可以使用tftp等工具。

 

  進行除錯:

  假設我們使用交叉編譯器產生了一個helloworld可執行程式,在目標板上執行:

  $> gdbserver 192.168.1.100:2345 helloworld

  其中 192.168.1.100 是除錯主機的地址,2345是除錯埠,helloword是需要除錯的可執行程式。

  隨後在主機上執行:

  $> gdb helloworld

  $> target remote 192.168.1.10:2345

  其中 192.168.1.10 是目標板的地址,2345是gdbserver開啟的用於建立除錯連線的埠。

 

可能遇到的問題:

  1. 在除錯實際模組的時候,設定了斷點一執行就表現出各種找不到動態連線庫(.so)

    可以這樣設定:set solib-search-path PATH

         通過上面設定告訴gdb所以來的動態庫在那裡,其中PATH是被除錯可執行程式所需的動態庫的位置,多個不同路徑可以使用“:”來隔開,這些路徑一般都是你價差編譯工具鏈的位置。

 

  2. 在除錯多執行緒程式的時候目標板出現“gdb: error initializing thread_db library”“Child terminated with signal 5

    出現這個問題的原因有很多,有可能是你目標板上沒有thread_db 庫,但是也有可能是你使用的gdb版本過低不支援多執行緒除錯(注意gdb7.0以下就不支援! 我當時一味的追求生成的檔案小就使用gdb6.3 這個問題一直沒有找到原因,折騰了一陣,最好也不要使用strip裁剪生成的可執行檔案)。

 

  3. 編譯gdb失敗:提示在linux-low.c中“siginfo isn’t known

    進入到linux-low.c 中,找到相應函式(大概有兩個函式),將 struct siginfo 全部換成為 siginfo_t。

 

  4. 多執行緒除錯可以設定 set follow-fork-mode child/parent

    表示在多執行緒中產生新執行緒的時候gdb進入到子執行緒還是父執行緒。

 

Gdb多執行緒除錯常用命令:

http://coolshell.cn/articles/3643.html

多執行緒除錯可能是問得最多的。其實,重要就是下面幾個命令:

  • info thread 檢視當前程式的執行緒。
  • thread <ID> 切換除錯的執行緒為指定ID的執行緒。
  • break file.c:100 thread all  在file.c檔案第100行處為所有經過這裡的執行緒設定斷點。
  • set scheduler-locking off|on|step,這個是問得最多的。在使用step或者continue命令除錯當前被除錯執行緒的時候,其他執行緒也是同時執行的,怎麼只讓被除錯程式執行呢?通過這個命令就可以實現這個需求。
    • off 不鎖定任何執行緒,也就是所有執行緒都執行,這是預設值。
    • on 只有當前被除錯程式會執行。
    • step 在單步的時候,除了next過一個函式的情況(熟悉情況的人可能知道,這其實是一個設定斷點然後continue的行為)以外,只有當前執行緒會執行。

相關文章