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不在主機端安裝運作。
- 可能的錯誤:提示缺少頭檔案
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CO2kjNyQjZiVTZ2UWNwEzMzYzX4MjM1kDM2IzLclDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
通過執行搜尋指令:grep “PTRACE_GETSIGINFO” * -nR,發現未定義的宏位于頭檔案位于
<linux/ptrace.h>
中,于是将其添加到linux-arm-low.c檔案的頭檔案聲明語句中。
沒有錯誤的話就在目前目錄下生成了
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