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

1.gdb和gdbserver調試原理

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

  和之前學的裸板GDB調試 一樣,只不過之前學的是在win下的,本次是在linux裏的gdb

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

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

1.2爲什麼需要調試信息的編譯文件?

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

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

  然後將地址發送給開發板裏的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§會調用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命令來調試

  常用命令如下所示:

  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,便可查看調用關係:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章