新聞中心
gdb是GNU開源組織發(fā)布的一個強(qiáng)大的Linux下的程序調(diào)試工具,主要來調(diào)試C/C++語言寫的程序,當(dāng)然也就可以調(diào)試其他語言程序,下面為大家詳細(xì)講解一下Linux下?gdb的使用方法。

名稱:
gdb-gnu調(diào)試器
概要:
gdb [-help] [-nx] [-q] [-batch] [-cd=dir] [-f] [-b bps] [-tty=dev] [-s symfile] [-e prog] [-se prog] [-c core] [-x cmds] [-d dir] [prog [core|procID]]
gdb [options] –args prog [arguments]
gdbtui [options]
說明:
gdb的目的主要是讓你知道程序內(nèi)部正在運(yùn)行什么代碼,或者是當(dāng)程序崩潰的時候正在執(zhí)行什么代碼
GDB主要可以做四種事情來幫助你找到bug:
? 啟動你的程序,指定任意可以影響程序行為的參數(shù)。
? 讓你的程序在指定的條件停住.
? 測試你的程序停止的時候發(fā)生了什么。
? 改變程序內(nèi)部的變量,來改正程序的錯誤繼續(xù)執(zhí)行。
你可以用gdb調(diào)試C/C++和modula-2程序,fortran的支持需要有Fortran編譯器
gdb使用shell命令gdb來調(diào)用,一旦開始,就從終端讀取命令直接gdb退出,你可以通過help命令獲取幫助信息。
可以不帶任何參數(shù)或選項執(zhí)行g(shù)db命令,但是最常用的啟動gdb的方式是帶一個或者兩個參數(shù),指定一個可執(zhí)行文件來作為參數(shù):
gdb program(gdb+可執(zhí)行文件名稱)
也可以再gdb文件后面指定可執(zhí)行文件 和 core文件的名稱:
gdb program core(gdb + 可執(zhí)行文件 +core文件)
You can, instead, specify a process ID as a second argument, if you want to debug a running process:
也可以指定一個進(jìn)程id作為第二個參數(shù),如果你想調(diào)試一個正在運(yùn)行的程序:
gdb program 1234(gdb進(jìn)程名+進(jìn)程id)
會附件gdb到進(jìn)程1234上(除非有一個文件名“1234”;GDB首先檢查core文件)
gdb調(diào)試命令:
break [file:]function
? 設(shè)置一個斷點(diǎn)在函數(shù)中(在文件中)
run [arglist]
? 啟動程序帶上指定的參數(shù)
bt Backtrace:
? 顯示堆棧
print expr
? 顯示表達(dá)式的值
c
? 繼續(xù)執(zhí)行你的程序(程序停住后,例如:在斷點(diǎn)處停止)
next
? 執(zhí)行程序的下一行代碼(程序停止以后);跨國任何當(dāng)前行的函數(shù)調(diào)用。
edit [file:]function
? 查看當(dāng)前程序停在哪。
list [file:]function
? 顯示程序當(dāng)前停住的代碼行附近的代碼
step 單步調(diào)試
? 執(zhí)行程序的下一行(程序停住后),進(jìn)入當(dāng)前行的函數(shù)調(diào)用的內(nèi)部
help [name]
? 顯示gdb命令的相關(guān)信息。
quit
? 退出gdb
需要詳細(xì)的gdb說明,查看using gdb:一個gdb調(diào)試程序的指南,stallmain和roland寫的,也有可用的在線文檔作為gdb入口在gdb項目信息中。
選項:
默認(rèn)的情況下,第一個選項就是執(zhí)行文件名(等同與”-se”),第二個選項就是core文件名(等同與”-c”),許多選項都有全稱和簡寫,如下:
全稱格式也是工人的,如果你截斷他們,只要足夠明確也可以使用。(如果你愿意的話,你可以“+”而不是“-”來標(biāo)記選項,盡管“-”是更常用的)。
所有的選項和命令行參數(shù)都是按順序處理的,當(dāng)使用-x選項的時候這個選項會不同。
-b bps
設(shè)置gdb遠(yuǎn)程調(diào)試的所有串行接口的速度
-batch
? 批處理執(zhí)行模式,處理完“-x”(和”.gdbinit”,如果不inhibited)指定的所有命令文件以返回碼0退出,如果出錯則返回非0,當(dāng)把gdb作為過濾器的時候,批處理模式非常有用,來在遠(yuǎn)程電腦上測試下載和執(zhí)行程序,為了確定它有用,程序退出的消息(當(dāng)一個程序在gdb模式下發(fā)布到控制終端的消息)不發(fā)布當(dāng)使用批處理模式的時候.
-c FILE, -core=FILE
? 使用文件作為一個coredump文件來測試
-cd=directory
? 指定工作目錄,不指定則為當(dāng)前目錄
-d DIRECTORY, -directory=DIRECTORY
? Add directory to the path to search for source files.
-e FILE, -exec=FILE
? 指定可執(zhí)行文件的名稱
-f, -fullname
? emacs設(shè)置這些選項當(dāng)把gdb作為一個子進(jìn)程的時候,告訴gdb在每次堆棧顯示時候以標(biāo)準(zhǔn)且可識別的方式輸出完整的文件名和行號(包含每次程序中斷的時候),可識別的形式看上去像兩個’32’字符開始,接下來是文件名,行號和字符位置和新行,他們用冒號分割,emacs-to-gdb接口程序用兩個‘32’字符作為信號來在一幀上顯示源代碼。
-h, -help
? 顯示幫助信息
-n, -nx
? 不要從任何”.gdbinit”結(jié)尾的初始化文件執(zhí)行,正常情況下,這種文件的命令在所有的命令行參數(shù)和選項處理完成之后才執(zhí)行。
-s FILE, -symbols=FILE
? 從文件中讀取符號表
-se=file
? 讀取符號表的文件和可執(zhí)行文件
q, -quiet
? 退出,不打印介紹信息和版權(quán)信息,這些消息在批處理模式下也不打印
-tty=device
? 使用設(shè)備來作為你的標(biāo)準(zhǔn)輸入和輸出
–args
? 在你的程序名后面?zhèn)鬟f參數(shù)當(dāng)程序執(zhí)行的時候。
-tui
運(yùn)行g(shù)db使用文檔(控制臺)用戶接口。
-write
允許寫入執(zhí)行文件和core文件
-x FILE, -command=FILE
從文件中執(zhí)行g(shù)db命令
二.實例
1.最簡單的gdb調(diào)試
文件名:add.c
代碼很簡單,實現(xiàn)一個加法,兩個數(shù)相加,輸出結(jié)果
#include
int add(int x,int y)
{
return x+y;
}
int main()
{
int x = 10;
int y = 20;
int num = add(x,y);
printf(” num = %d\n”,num);
return 0;
}
編譯gcc -g add.c生成a.out文件(注意編譯的時候一定要加上-g選項才能使用gdb調(diào)試程序)
gdb ./a.out
img
上圖中有一個警告信息,因為我是源代碼安裝的,拷貝gdb下的python庫到指定的目錄即可(警告中的目錄)
輸入help可以查看幫助信息
img
start啟動程序
img
可以使用n,s命令跑完整個程序,很簡單,可以通過這個簡單的demo熟悉一下gdb的各種命令。
img
2.gdb多進(jìn)程調(diào)試
gdb調(diào)試多進(jìn)程的命令:
set follow-fork-mode mode設(shè)置調(diào)試器的模式
mode參數(shù)可以是
parent fork之后調(diào)試原進(jìn)程,子進(jìn)程不受影響,這是缺省的方式
child fork之后調(diào)試新的進(jìn)程,父進(jìn)程不受影響。
show follow-fork-mode 顯示當(dāng)前調(diào)試器的模式
set detach-on-fork mode 設(shè)置gdb在fork之后是否detach進(jìn)程中的其中一個,或者繼續(xù)保留控制這兩個進(jìn)程
on 子進(jìn)程(或者父進(jìn)程,依賴于follow-fork-mode的值)會detach然后獨(dú)立運(yùn)行,這是缺省的mode
off 兩個進(jìn)程都受gdb控制,一個進(jìn)程(子進(jìn)程或父進(jìn)程,依賴于follow-fork-mode)被調(diào)試,另外一個進(jìn)程被掛起
info inferiors 顯示所有進(jìn)程
inferiors processid 切換進(jìn)程
detach inferiors processid detach 一個由指定的進(jìn)程,然后從fork 列表里刪除。這個進(jìn)程會被
允許繼續(xù)獨(dú)立運(yùn)行。
kill inferiors processid 殺死一個由指定的進(jìn)程,然后從fork 列表里刪除。
catch fork 讓程序在fork,vfork或者exec調(diào)用的時候中斷
實例:fork.c
#include
#include
#include
#include
int add(int x,int y)
{
return x+y;
}
int test()
{
int num = 0;
pid_t pid = fork();
if(pid == 0)
{
while(1)
{
? num = add(1,2);
? printf(“child:pid:%d num = %d\n”,getpid(),num);
? sleep(1);
}
exit(0);
}
while(1){
num = add(10,20);
printf(“parent:pid:%d num = %d\n”,getpid(),num);
sleep(1);
}
return 0;
}
int main()
{
test();
return 0;
}
編譯 gcc -g fork.c
設(shè)置catch fork,查看 follow-fork-mode和detach-on-fork的默認(rèn)值
img
設(shè)置detach-on-fork為off,start啟動程序,會再fork斷點(diǎn)處停止
img
再兩個進(jìn)程中的add函數(shù)分別設(shè)置端點(diǎn):
img
繼續(xù)執(zhí)行程序,info inferiors顯示進(jìn)程
img
inferiors 2切換進(jìn)程
img
detach inferiors 2
img
重新啟動gdb來測試kill inferiors 2,如下圖
img
3.gdb多線程調(diào)試
gdb調(diào)試多線程的命令:
info threads 查詢線程信息
thread threadno 切換線程
thread apply [threadno] [all] args 對線程列表執(zhí)行命令
set print thread-events 控制線程開始和結(jié)束時的打印信息
show print thread-events 顯示線程打印信息的開關(guān)狀態(tài)
實例:文件名thread.c
代碼很簡單如下:
#include
#include
#include
int add(int x,int y)
{
return x+y;
}
void* thread(void *args)
{
int num = 0;
while(1)
{
num += add(1,2);
sleep(1);
}
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, thread, NULL);
int num = 0;
while(1)
{
num += add(10,20);
sleep(1);
}
return 0;
}
編譯gcc -g thread.c -lpthread(鏈接pthread線程庫)
gdb調(diào)試:gdb ./a.out
在線程中兩個調(diào)用add函數(shù)的位置分別設(shè)置斷點(diǎn)
img
start啟動程序,c繼續(xù)執(zhí)行程序直到斷點(diǎn)處
info threads顯示當(dāng)前程序中的線程
img
c繼續(xù)執(zhí)行程序,到達(dá)第二個程序再執(zhí)行info threads命令,發(fā)現(xiàn)當(dāng)前程序發(fā)生了線程切換,由線程2變?yōu)榫€程1
img
thread 2手動切換線程到線程2,再執(zhí)行info threads查看當(dāng)前線程
img
使用thread apply 命令的示例:
img
set print thread-events on/off 這里默認(rèn)是開啟的
show print thread-events
img
img
日記本
本文名稱:詳解Linux程序調(diào)試工具gdb
標(biāo)題路徑:http://www.dlmjj.cn/article/cdsdsgg.html


咨詢
建站咨詢
