天天看點

gdb+gdbserver調試詳解

1、gdb+gdbserver總體介紹

遠端調試環境由主控端GDB和目标機調試stub共同構成,兩者通過序列槽或TCP連接配接。使用 GDB标準串行協定協同工作,實作對目标機上的系統核心和上層應用的監控和調試功能。調試stub是嵌入式系統中的一段代碼,作為主控端GDB和目标機調試程式間的一個媒介而存在。

就目前而言,嵌入式Linux系統中,主要有三種遠端調試方法,分别适用于不同場合的調試工作:

  • 普通項目用ROM Monitor調試目标機程式
  • 用KGDB調試系統核心
  • 用gdbserver調試使用者空間程式

這三種調試方法的差別主要在于,目标機遠端調試stub 的存在形式的不同,而其設計思路和實作方法則是大緻相同的。我們最常用的是調試應用程式就是采用gdb+gdbserver的方式進行調試。

在很多情況下,使用者需要對一個應用程式進行反複調試,特别是複雜的程式。采用GDB方法調試,由于嵌入式系統資源有限性,一般不能直接在目标系統上進行調試,通常采用gdb+gdbserver的方式進行調試。

2、gdb下載下傳、配置、編譯和安裝

2.1 gdb源代碼下載下傳

嵌入式Linux的GDB調試環境由主機和開發闆兩部分組成,主機端使用​

​arm-linux-gdb​

​​,開發闆端使用​

​gdbserver​

​(在主機上針對特定硬體平台編譯成功後下載下傳到目标機上)。

因為應用程式是在開發闆上運作,而gdb調試是在主機端,是以需要采用遠端調試(remote)的方法。

一般Linux發行版中都有一個可以運作的GDB,但開發人員不能直接使用該發行版中的GDB來做遠端調試,而是要擷取GDB的源代碼包,針對arm 平台作一個簡單配置,重新編譯得到相應GDB。

當然,如果晶片商提供的交叉編譯套件中已經包含了arm-linux-gdb,我們就不用重新編譯gdb了,直接用它即可。不管怎麼說,gdbserver還是需要用目标闆的toolchain重新編譯一遍,因為晶片商提供的交叉開發套件通常不包括gdbserver。

GDB的源代碼包可以從GNU官網中下載下傳。

2.2 配置編譯及安裝

假設源代碼已經下載下傳到/opt目錄,解壓:

cd /opt
tar      

2.2.1 arm-linux-gdb編譯

cd /opt
mkdir arm-gdb/
cd gdb-6.8
./configure --target=arm-linux --prefix=/opt/arm-gdb
make
make install      

上面指令中,–target配置gdb的目标平台,–prefixp指定了編譯結果的存放位置,也就是安裝目錄。

編譯完後可以在/opt/arm-gdb/bin目錄下找到可執行的arm-linux-gdb。拷貝arm-linux-gdb 到/usr/bin目錄:

cd /opt/arm-gdb/bin/
cp arm-linux-gdb /usr/bin/
cd      

2.2.2 gdbserver編譯

下面把 gdbserver 移植到ARM平台。要點是指定目标平台的交叉編譯鍊(gcc和ar)。我們建立一個臨時的編譯目錄,以避免弄髒原代碼。

cd gdb-6.8/gdb/gdbserver
./configure  --host=arm-linux
make      

上面指令中,–host=arm-linux表示運作在ARM目标平台上,不需要配置—prefix,因為gdbserver不在主機端安裝運作。

  • 可能的錯誤:提示缺少頭檔案
gdb+gdbserver調試詳解

通過執行搜尋指令:grep “PTRACE_GETSIGINFO” * -nR,發現未定義的宏位于頭檔案位于​

​<linux/ptrace.h>​

​中,于是将其添加到linux-arm-low.c檔案的頭檔案聲明語句中。

gdb+gdbserver調試詳解

沒有錯誤的話就在目前目錄下生成了​

​gdbserver​

​可執行檔案.

注意此時要更改其屬性,否則可能會出現無法通路的情況,chmod 777 gdbserver将其更改為任何人都可以讀寫執行;

使用arm-linux-strip指令處理一下gdbserver,将多餘的符号資訊删除,可讓elf檔案更精簡,通常在應用程式的最後釋出時使用;

然後把它燒寫到flash的根檔案系統分區的/usr/bin(在此目錄下,系統可以自動找到應用程式,否則必須到gdbserver所在目錄下運作之),或通過nfs mount的方式都可以,隻要保證gdbserver能在開發闆上運作就行。

編譯好gdbserver後,把它拷貝到目标闆上的 /usr/bin 目錄下,運作後,如果能顯示幫助資訊,則交叉編譯成功,如:

gdbserver
Usage:  gdbserver [OPTIONS] COMM PROG [ARGS ...]
        gdbserver [OPTIONS] --attach COMM PID
        gdbserver [OPTIONS] --multi COMM

COMM may either be a tty device (for serial debugging), or 
HOST:PORT to listen for      

如果提示其它錯誤資訊,如二進制檔案無法執行,則表示編譯不成功。注意我們交叉編出來的gdbserver是無法在開發主機上運作的。

3、指令行遠端調試

  • 在目标闆上,運作 gdbserver 指令啟動測試程式的調試,并指定目标闆的IP和監聽端口号,如:
gdbserver 192.168.1.120:1234 ./test_file(要調試的程式)
Process test_file created; pid = 625
Listening on port 1234      
  • 在開發主機上運作 arm-linux-gdb,指定gdbserver的IP和端口,連接配接上去,如:
arm-linux-gdb ./test_file
...
(gdb) target remote 192.168.1.120:1234
Remote debugging using 192.168.1.120:1234
0x400b57f0 in ?? ()      

4、本地調試

  • 基本原理:在開發闆上運作待調試程式,待其發生錯誤産生core dump檔案(需要設定允許産生dump檔案)後,将dump檔案複制到主機上,利用gdb程式對其進行調試。
  • 步驟:
  • 開發闆上執行:
ulimite -c unlimited
./test_file            //應用出錯,産生core dump檔案
cp ./core dir(主機上的待調試檔案test_file所在目錄)      
  • 主機上執行:
cd dir      

繼續閱讀