40.Linux應用調試-使用gdb和gdbserver

1.gdb和gdbserver調試原理html

經過linux虛擬機裏的gdb,來向開發板裏的gdbserver發送命令,好比設置斷點,運行setp等,而後開發板上的gdbserver收到命令後,便會執行應用程序作相應的動做,來實現調試的功能linux

和以前學的裸板GDB調試 同樣,只不過以前學的是在win下的,本次是在linux裏的gdb服務器

1.1一樣,它們都會須要一個帶調試信息的編譯文件.函數

經過Makefile裏的arm-linux-gcc  -g 來的,     -g:表示編譯文件裏包含gdb調試信息測試

1.2爲何須要調試信息的編譯文件?ui

好比讀開發板的應用程序裏的變量a:spa

首先gdb經過應用程序的帶調試信息的編譯文件,來找出變量a存的地址位置debug

而後將地址發送給開發板裏的gdbserver,來讀出a地址的值指針

 

2.安裝gdb和gdbserver 調試

首先進入官網下載gdb-7.4: http://ftp.gnu.org/gnu/gdb/ 

2.1在虛擬機上安裝GDB:  

# tar xjf gdb-7.4.tar.bz2                  //解壓
 # cd gdb-7.4/                              //進入gdb-7.4目錄
 #./configure --target=arm-linux //GDB須要在pc本機裏運行,並調試開發板裏的應用程序,因此--target設爲arm-linux
 #make //編譯
 #mkdir tmp #make install prefix=$PWD/tmp              //安裝到./tmp目錄下
 sudo cp tmp/bin/arm-linux-gdb  /bin/       //複製到/bin目錄下

/bin/arm-linux-gdb  -v                     //-v: 肯定一下gdb的版本VID,是不是7.4

2.2 在開發板上安裝GDBServer:

cd gdb/gdbserver/                                   //在gdb-7.4目錄下輸入
 ./configure --target=arm-linux --host=arm-linux              //設GDBServer的工做環境
 make //編譯

出現如下錯誤:

指在linux-arm-low.c裏,沒有找到PTRACE_GETSIGINFO 定義

2.3 解決:

1) 

#echo $PATH     //來查看PATH環境變量

找到編譯器gcc位於/work/tools/gcc-3.4.5-glibc-2.3.6/bin

2)

#cd /work/tools/gcc-3.4.5-glibc-2.3.6/     # grep "PTRACE_GETSIGINFO"  *  -nR

在gcc根目錄下,搜索到在linux/ptrace.h中定義:

 

3)

#vi linux-arm-low.c

添加: #define PTRACE_GETSIGINFO 0x4202

4)最後從新make,生成gdbserver命令文件

而後將gdbserver命令文件,放入咱們開發板的根目錄/bin中,便能使用了

cp  gdbserver  /nfs_root/bin/          //nfs_root:開發板的nfs系統根目錄

3.測試程序以下(test_debug.c)

#include <stdio.h>

void  C(int *p) {    *p = 0x12; } void  B(int *p) {   C(p); } void  A(int *p) {   B(p); } void  A2(int *p) {   C(p); } int  main(int argc, char **argv) {   int a;   int *p = NULL;   A2(&a);  // A2 > C   printf("a = 0x%x\n", a);   A(p); // A > B > C
  return 0; }

其中A2(&a)會調用A2()->C(),而後將a賦值爲0x12.

A(p)會調用A()->B()->C(),因爲p是個空指針,這裏將會出錯.

接下來,咱們便以這個應用程序爲例.

4.編譯

#arm-linux-gcc -g -o test_debug test_debug.c   //-g:附帶調試信息

5.調試test_debug.c

在開發板上:

首先,須要讓gdbserver創建本地服務器,以及要測試的哪一個文件:

#gdbserver 192.168.2.107:2345 ./test_debug //192.168.2.107:本地IP地址 //2345:端口號,用來讓gdb來鏈接用的 //./test_debug:要測試的哪一個文件

在虛擬機上:

#/bin/arm-linux-gdb   ./test_debug    // 啓動gdb,指定調試文件爲test_debug
 #target remote 192.168.2.107:2345    //與gdbserver創建鏈接

5.1鏈接成功,便使用gdb命令來調試

經常使用命令以下所示(參考http://blog.sciencenet.cn/blog-619295-813770.html):

l

列出全部源代碼

break [file]:[row]

打斷點,好比:

break test_debug.c:21     //在test_debug.c文件的第21行處打斷點

info br

查看斷點

 

info file

 

列出當前的文件,共享庫。

 

delete <num>

刪除第幾個斷點,以下圖所示:

 

c

啓動程序運行 

step

單步執行

next  

單步執行,和step不一樣的是,好比:當前行裏有函數調用時,next直接執行下一句,step會進入函數

print a

打印a變量的值

quit

退出gdb

 

6.也能夠經過gdb+coredump來調試test_debug.c

當程序運行出錯時,便會生成core文件,並將程序裏的運行情況存到core中,也就是coredump,供給gdb來調試

6.1首先,經過ulimit來查看coredump的資源大小     

ulimit命令(user limit),主要用來限制用戶的各個進程資源.

在開發板裏,輸入

 

如上圖所示,能夠看到coredump的資源大小爲0,也就是說,當程序運行出錯時,不會生成core文件

6.2設置core文件

設置core文件的資源大小爲無限制,輸入:

ulimit -c unlimited
 //-c:對應coredump

6.3生成core文件

執行:

#./test_debug

出現段錯誤,並生成core文件,以下圖所示:

 

6.4 進入虛擬機

core拷貝過來,而後執行:

#/bin/arm-linux-gdb ./test_debug ./core

而後輸入bt,即可查看調用關係:

 

相關文章
相關標籤/搜索