GDB的使用
GDB的使用
1)使用GCC编译时加参数 –g 例:gcc tmp01.c –o tmp01 -g
2)gdb tmp01
3)(gdb) l : 查看载入的文件(list)
4)(gdb) b 6 : 在第6行处设置断点
5)(gdb) info b : 查看设置的断点情况
6)(gdb) r : 开始运行程序,+行号可以从指定行开始运行
7)(gdb) p n : 查看变量的值
8)(gdb) watch n : 设置观察点(变量)
9)(gdb) n : 单步运行(next)
10) (gdb) c : 程度继续运行(continue)
|
GDB中常见断点设置与删除指令 |
|
|
|
break+设置断点的行号 |
用于在程序中对应行设置断点 |
|
|
tbreak+行号或函数名 |
设置临时断点,到达后被自动删除 |
|
|
break+filename+行号 |
用于在指定文件的对应行设置断点 |
|
|
break+<0x..> |
用于在内存某一位置处暂停 |
|
|
break+行号+if+条件 |
用于设置条件断点,在循环中使用非常方便 |
|
|
info breakpoints/watchpoints |
查看断点/观察点的情况 |
|
|
clear+要清除断点的行号 |
用于清除对应行的断点 |
|
|
delete+要清除断点的编号 |
用于清除断点和自动显示的表达式的命令。与clear的不同之处:clear要给出断点的行号,delete要给出断点的编号。用clear命令清除断点时GDB会给出提示,而用delete清除断点时GDB不会给出任何提示。 |
|
|
disable+断点编号 |
让所设断点暂时失效。如果要让多个编号处的断点失效可将编号之间用空格隔开。 |
|
|
enable+断点编号 |
与disable相反 |
|
|
awatch+变量 |
设置一个观察点,当变量被读出或写入时程序被暂停 |
|
|
rwatch+变量 |
设置一个观察点,当变量被程序读时,程序被暂停 |
|
|
watch |
同awatch |
|
|
GDB中数据相关指令 |
|
|
|
display+表达式 |
该命令用于显示表达式的值,使用了该命令后,每当程序运行到断点处都会显示表达式的值 |
|
|
info display |
用于显示当前所有要显示值的表达式的有关情况 |
|
|
delete+display 编号 |
用于删除一个要显示价目表的表达工,调用这个命令删除一个表达式后,被删除的表达式将不被显示 |
|
|
disable+display 编号 |
使一个要显示的表达式暂时无效 |
|
|
enable+display 编号 |
disable display 的反操作 |
|
|
undisplay+display 编号 |
用于结束某个表达式值的显示 |
|
|
whatis+变量 |
显示某个表达式的数据类型 |
|
|
print(p)+变量或表达式 |
用于打印变量或表达式的值 |
|
|
set+变量=变量值 |
改变程序中一个变量的值 |
|
|
GDB调试运行环境相关命令 |
||
|
set args |
设置运行参数 |
|
|
show args |
参看运行参数 |
|
|
set width+数目 |
设置GDB的行宽 |
|
|
cd+工作目录 |
切换工作目录 |
|
|
run |
程序开始执行 |
|
|
step(s) |
进入式(会进入到所调用的子函数中)单步执行 |
|
|
next(n) |
非进入式(不会进入到时所调用的子函数中)单步执行 |
|
|
finish |
一直运行到函数返回 |
|
|
until+行数 |
运行到函数某一行 |
|
|
continue(c) |
执行到下一断点或程序结束 |
|
|
return <返回值> |
改变程序流程,直接结束当前函数,并将指定值返回 |
|
|
call+函数 |
在当前位置执行所要运行的函数 |
|
|
GDB中堆栈相关命令 |
||
|
backtrace/bt |
用来打印栈侦指针,也可以在该命令后加上要打印的栈侦指针的个数 |
|
|
frame |
用于打印栈侦 |
|
|
info reg |
查看寄存器的使用情况 |
|
|
info stack |
查看堆栈情况 |
|
|
up |
跳到上一层函数 |
|
|
down |
与up相对 |
|
编译时必须加上参数-g ,例:g++ -g temp.cpp -o temp.通过Gcc编译生成可执行文件才能用Gdb进行调试。
进入gdb界面:gdb temp. 提示符变成(gdb)
(1)查看文件
在Gdb中键入”l”(list)就可以查看所载入的文件
(2)设置断点
只需在”b”后加入对应的行号即可(这是最常用的方式,另外还有其他方式设置断点)。如下所示:
(gdb)b 6
代码运行到第五行之前暂停(并没有运行第五行)。
(3)查看断点情况
(Gdb) info b
(4)运行代码
Gdb默认从首行开始运行代码,可键入”r”(run)即可(若想从程序中指定行开始运行,可在r后面加上行号)。
(5)查看变量值
查看断点处的相关变量值。在Gdb中只需键入”p”+变量值即可,如下所示:
(Gdb) p n
Gdb在显示变量值时都会在对应值之前加上”$N”标记,它是当前变量值的引用标记,所以以后若想再次引用此变量就可以直接写作”$N”,而无需写冗长的变量名。
(6)单步运行
使用命令”n”(next)或”s”(step),它们之间的区别在于:若有函数调用的时候,”s”会进入该函数而”n”不会进入该函数。因此,”s”就类似于VC等工具中的”step in”,”n”类似与VC等工具中的”step over”。
(7)恢复程序运行
使用命令”c”(continue).
在Gdb中,程序的运行状态有“运行”、“暂停”和“停止”三种,其中“暂停”状态为程序遇到了断点或观察点之类的,程序暂时停止运行,而此时函数的地址、函数参数、函数内的局部变量都会被压入“栈”(Stack)中。故在这种状态下可以查看函数的变量值等各种属性。但在函数处于“停止”状态之后,“栈”就会自动撤销,它也就无法查看各种信息了。
Gdb中的命令主要分为以下几类:工作环境相关命令、设置断点与恢复命令、源代码查看命令、查看运行数据相关命令及修改运行参数命令。以下就分别对这几类的命令进行讲解。
1.工作环境相关命令
|
set args运行时的参数 |
指定运行时参数,如:set args 2 |
|
show args |
查看设置好的运行参数 |
|
path dir |
设定程序的运行路径 |
|
show paths |
查看程序的运行路径 |
|
set enVironment var [=value] |
设置环境变量 |
|
show enVironment [var] |
查看环境变量 |
|
cd dir |
进入到dir目录,相当于shell中的cd命令 |
|
pwd |
显示当前工作目录 |
|
shell command |
运行shell的command命令 |
2.设置断点与恢复命令
|
info b |
查看所设断点 |
|
break 行号或函数名 <条件表达式> |
设置断点 |
|
tbreak 行号或函数名 <条件表达式> |
设置临时断点,到达后被自动删除 |
|
delete [断点号] |
删除指定断点,其断点号为”info b”中的第一栏。若缺省断点号则删除所有断点 |
|
disable [断点号]] |
停止指定断点,使用”info b”仍能查看此断点。同delete一样,省断点号则停止所有断点 |
|
enable [断点号] |
激活指定断点,即激活被disable停止的断点 |
|
condition [断点号] <条件表达式> |
修改对应断点的条件 |
|
ignore [断点号]<num> |
在程序执行中,忽略对应断点num次 |
|
step |
单步恢复程序运行,且进入函数调用 |
|
next |
单步恢复程序运行,但不进入函数调用 |
|
finish |
运行程序,直到当前函数完成返回 |
|
c |
继续执行函数,直到函数结束或遇到新的断点 |
由于设置断点在Gdb的调试中非常重要,所以在此再着重讲解一下Gdb中设置断点的方法。
Gdb中设置断点有多种方式:其一是按行设置断点,设置方法在3.5.1节已经指出,在此就不重复了。另外还可以设置函数断点和条件断点,在此结合上一小节的代码,具体介绍后两种设置断点的方法。
① 函数断点
(gdb) b 函数名
② 条件断点
格式为:b 行数或函数名 if 表达式
(gdb) b 8 if i==10
3.Gdb中源码查看相关命令
|
list <行号>|<函数名> |
查看指定位置代码 |
|
file [文件名] |
加载指定文件 |
|
forward-search 正则表达式 |
源代码前向搜索 |
|
reverse-search 正则表达式 |
源代码后向搜索 |
|
dir dir |
停止路径名 |
|
show directories |
显示定义了的源文件搜索路径 |
|
info line |
显示加载到Gdb内存中的代码 |
4.Gdb中查看运行数据相关命令
指当程序处于“运行”或“暂停”状态时,可以查看的变量及表达式的信息
|
print 表达式|变量 |
查看程序运行时对应表达式和变量的值 |
|
x <n/f/u> |
查看内存变量内容。其中n为整数表示显示内存的长度,f表示显示的格式,u表示从当前地址往后请求显示的字节数 |
|
display 表达式 |
设定在单步运行或其他情况中,自动显示的对应表达式的内容 |
5.Gdb中修改运行参数相关命令
Gdb还可以修改运行时的参数,并使该变量按照用户当前输入的值继续运行。它的设置方法为:在单步执行的过程中,键入命令“set 变量=设定值”。这样,在此之后,程序就会按照该设定的值运行了。下面,笔者结合上一节的代码将n的初始值设为4,其代码如下所示:
(Gdb) b 7
Breakpoint 5 at 0x804847a: file test.c, line 7.
(Gdb) r
Starting program: /home/yul/test
The sum of 1-m is 1275
Breakpoint 5, main () at test.c:7
7 for(i=1; i<=50; i++)
(Gdb) set n=4
(Gdb) c
Continuing.
The sum of 1-50 is 1279
Program exited with code 031.
可以看到,最后的运行结果确实比之前的值大了4。
Gdb的使用切记点:
· 在Gcc编译选项中一定要加入”-g”。
· 只有在代码处于“运行”或“暂停”状态时才能查看变量值。
· 设置断点后程序在指定行之前停止。
http://www.cnblogs.com/rosesmall/archive/2012/04/13/2445300.html
gdb使用
在linux下做东西,gcc,gdb是避不开的,刚开始使用比较麻烦,永久了感觉还是挺好用的。redhat里面自带一个gdb的图形前端kdbg,升级到高一点的版本还是挺好用的。还有一个xxgdb,没用过,不知道怎么样。
一、初始化
输入gdb进入gdb调试环境。或者直接输入gdb + progfile来加载文件。
注意该文件是使用gcc(或g++)编译得到的。为了使 gdb 正常工作, 必须
使你的程序在编译时包含调试信息,编译时必须使用-g参数来。
或者进入gdb环境后,通过命令file + progfile来加载需要调试的可
执行文件文件。
查看源代码:list [函数名][行数]
设置程序运行参数:set args
二、暂停程序
gdb可以使用几种方式来暂停程序:断点,观察点,捕捉点,信号,线
程停止。当程序被暂停后,可以使用continue、next、setp来继续执行程序。
continue 执行到下一暂停点或程序结束。
next 执行一行源代码但不进入函数内部。
setp 执行一行源代码而且进入函数内部。
1、设置断点:
a、break + [源代码行号][源代码函数名][内存地址]
b、break ... if condition ...可以是上述任一参数,condition
条件。例如在循环体中可以设置break ... if i = 100 来设置循环次数。
2、设置观察点:
a、watch + [变量][表达式] 当变量或表达式值改变时即停住程序。
b、rwatch + [变量][表达式] 当变量或表达式被读时,停住程序。
c、awatch + [变量][表达式] 当变量或表达式被读或被写时,停住程序。
3、设置捕捉点:
catch + event 当event发生时,停住程序。event可以是下面的内容:
1)、throw 一个C++抛出的异常。(throw为关键字)
2)、catch 一个C++捕捉到的异常。(catch为关键字)
3)、exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用)
4)、fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用)
5)、vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用)
6)、load 或 load 载入共享库(动态链接库)时。(load为关键字,
目前此功能只在HP-UX下有用)
7)、unload 或 unload 卸载共享库(动态链接库)时。(unload为关
键字,目前此功能只在HP-UX下有用)
4、捕捉信号:
handle + [argu] + signals
signals:是Linux/Unix定义的信号,SIGINT表示中断字符信号,也就是
Ctrl+C的信号,SIGBUS表示硬件故障的信号;SIGCHLD表示子进程状态改
变信号; SIGKILL表示终止程序运行的信号,等等。
argu:
nostop 当被调试的程序收到信号时,GDB不会停住程序的运行,但
会打出消息告诉你收到这种信号。
stop 当被调试的程序收到信号时,GDB会停住你的程序。
print 当被调试的程序收到信号时,GDB会显示出一条信息。
noprint 当被调试的程序收到信号时,GDB不会告诉你收到信号的信息。
pass or noignore 当被调试的程序收到信号时,GDB不处理信号。
这表示,GDB会把这个信号交给被调试程序会处理。
nopass or ignore 当被调试的程序收到信号时,GDB不会让被调
试程序来处理这个信号。
5、线程中断:
break [linespec] thread [threadno] [if ...]
linespec 断点设置所在的源代码的行号。如: test.c:12表示文件为
test.c中的第12行设置一个断点。
threadno 线程的ID。是GDB分配的,通过输入info threads来查看正在
运行中程序的线程信息。
if ... 设置中断条件。
三、查看信息
1、查看数据
print variable 查看变量
print *array@len 查看数组(array是数组指针,len是需要数据长度)
可以通过添加参数来设置输出格式:
/x 按十六进制格式显示变量。
/d 按十进制格式显示变量。
/u 按十六进制格式显示无符号整型。
/o 按八进制格式显示变量。
/t 按二进制格式显示变量。
/a 按十六进制格式显示变量。
/c 按字符格式显示变量。
/f 按浮点数格式显示变量。
2、查看内存
examine /n f u + 内存地址(指针变量)
n 表示显示内存长度
f 表示输出格式(见上)
u 表示字节数制定(b 单字节;h 双字节;w 四字节;g 八字节;默认为四字节)
如:
x /10cw pFilePath (pFilePath为一个字符串指针,指针占4字节)
x 为examine命令的简写。
3、查看栈信息
backtrace [-n][n]
n 表示只打印栈顶上n层的栈信息。
-n 表示只打印栈底上n层的栈信息。
不加参数,表示打印所有栈信息。
附注:
基本gdb命令:
---------------------------------------------------------------------
命令 简写 功能
---------------------------------------------------------------------
file 装入想要调试的可执行文件.
kill k 终止正在调试的程序.
list l 列出产生执行文件的源代码的一部分.
next n 执行一行源代码但不进入函数内部.
step s 执行一行源代码而且进入函数内部.
continue c 继续执行程序,直至下一中断或者程序结束。
run r 执行当前被调试的程序.
quit q 终止 gdb.
watch 使你能监视一个变量的值而不管它何时被改变.
catch 设置捕捉点.
thread t 查看当前运行程序的线程信息.
break b 在代码里设置断点, 这将使程序执行到这里时被挂起.
make 使你能不退出 gdb 就可以重新产生可执行文件.
shell 使你能不离开 gdb 就执行 UNIX shell 命令.
print p 打印数据内容。
examine x 打印内存内容。
backtrace bt 查看函数调用栈的所有信息。
下面先说明GDB的基本指令:(使用时只要输入第一个字母就好了)
f(ile) :指定一个可执行文件进行调试,gdb将读取些文件的调试讯息,如f a.exe
l(ist):列程序出源文件
r(un):装载完要调试的可执行文件后,可以用run命令运行可执行文件
b(reak):设置断点(break point),如b 25,则在源程序的第25行设置一个断点,当程序执行到第25行时,就会产生中断;也可以使用b funcname,funcname为函数的名称,当程序调用些函数时,则产生中断
c(ontinue):c命令可以另中断的程序继续执行,直到下一个中断点或程序结束
p(rint):输入某个变量的值,如程序定义了一个int aa的就是,p aa就会输出aa的当前值
n(ext):程序执行到断点时中断执行,可以用n指令进行单步执行
s(tep):程序执行到断点时中断执行,可以用s指令进行单步执行进某一函数
kill: 终止正在调试的程序
watch: 使你能监视一个变量的值而不管它何时改变
make: 使你能不退出gdb就可以重新产生可执行文件
shell:使你能不退出gdb就可以执行shell命令
q(uit):退出GDB
现在让我们来举一个简单的例子来说明GDB的使用,假设我们有以下的程序:
/****************************************************************************
gdb_sample.c
****************************************************************************/
#i nclude <stdio.h>
void PrintLn(const char* pMsg)
{
printf(“%s\n”, pMsg);
}
int main(int argc, char* argv[])
{
PrintLn(“Hello GDB”);
return 0;
}
调行以下命令编译程序gcc –g gdb_sample.c –o a.exe,生成a.exe的可执行文件。要用GDB调试程序,执行:
gdb a.exe
这样,我们就进入了gdb的调试环境。在gdb的命令行中输入list,gdb就会把上面的源程序打印出来,再次输入list,则进行翻页。接着,我们输入b 13,表示在源程序的第13行PrintLn("Hello GDB")设置断点。设置断点后我们开始执行程序,在命令行中输入run,a.exe就开始执行。由于我们在第13行设置了断点,因此,程序会在PrintLn("Hello GDB")处中断,此时,我们可以输入s,gdb会单步运行进PrintLn函数内,接着输入n,程序就会执行此语句:printf("%s\n", pMsg),此时,我们再输入print pMsg,gdb就会输出pMsg的值:“Hello GDB”。最后,我们输入c,程序继续执行,然后正常退出。
http://blog.163.com/rjwhh@126/blog/static/2333770720074244283422/

浙公网安备 33010602011771号