用 gdb 调试 GCC 程序Word格式文档下载.docx
《用 gdb 调试 GCC 程序Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《用 gdb 调试 GCC 程序Word格式文档下载.docx(10页珍藏版)》请在冰豆网上搜索。
list
输出从上次调用list命令开始往后的10行程序代码。
list-
输出从上次调用list命令开始往前的10行程序代码。
listn
输出第n行附近的10行程序代码。
listfunction
输出函数function前后的10行程序代码。
*forward/search:
从当前行向后查找匹配某个字符串的程序行。
使用格式:
forward/search字符串
查找到的行号将保存在$_变量中,可以用print$_命令来查看。
*reverse-search:
和forward/search相反,向前查找字符串。
使用格式同上。
*break:
在程序中设置断点,当程序运行到指定行上时,会暂停执行。
break要设置断点的行号
*tbreak:
设置临时断点,在设置之后只起作用一次。
tbreak要设置临时断点的行号
*clear:
和break相反,clear用于清除断点。
clear要清除的断点所在的行号
*run:
启动程序,在run后面带上参数可以传递给正在调试的程序。
*awatch:
用来增加一个观察点(addwatch),使用格式:
awatch变量或表达式
当表达式的值发生改变或表达式的值被读取时,程序就会停止运行。
*watch:
与awatch类似用来设置观察点,但程序只有当表达式的值发生改变时才会停止运行。
使用格式:
watch变量或表达式
需要注意的是,awatch和watch都必须在程序运行的过程中设置观察点,即可运行run之后才能设置。
*commands:
设置在遇到断点后执行特定的指令。
使用格式有:
commands
设置遇到最后一个遇到的断点时要执行的命令
commandsn
设置遇到断点号n时要执行的命令
注意,commands后面跟的是断点号,而不是断点所在的行号。
在输入命令后,就可以输入遇到断点后要执行的命令,每行一条命令,在输入最后一条命令后输入end就可以结束输入。
*delete:
清除断点或自动显示的表达式。
delete断点号
*disable:
让指定断点失效。
disable断点号列表
断点号之间用空格间隔开。
*enable:
和disable相反,恢复失效的断点。
enable断点编号列表
*ignore:
忽略断点。
ignore断点号忽略次数
*condition:
设置断点在一定条件下才能生效。
condition断点号条件表达式
*cont/continue:
使程序在暂停在断点之后继续运行。
cont
跳过当前断点继续运行。
contn
跳过n次断点,继续运行。
当n为1时,cont1即为cont。
*jump:
让程序跳到指定行开始调试。
jump行号
*next:
继续执行语句,但是跳过子程序的调用。
next
执行一条语句
nextn
执行n条语句
*nexti:
单步执行语句,但和next不同的是,它会跟踪到子程序的内部,但不打印出子程序内部的语句。
*step:
与next类似,但是它会跟踪到子程序的内部,而且会显示子程序内部的执行情况。
*stepi:
与step类似,但是比step更详细,是nexti和step的结合。
*whatis:
显示某个变量或表达式的数据类型。
whatis变量或表达式
*ptype:
和whatis类似,用于显示数据类型,但是它还可以显示typedef定义的类型等。
ptype变量或表达式
*set:
设置程序中变量的值。
set变量=表达式
set变量:
=表达式
*display:
增加要显示值的表达式。
display表达式
*infodisplay:
显示当前所有的要显示值的表达式。
*deletedisplay/undisplay:
删除要显示值的表达式。
deletedisplay/undisplay表达式编号
*disabledisplay:
暂时不显示一个要表达式的值。
disabledisplay表达式编号
*enabledisplay:
与disabledisplay相反,使用表达式恢复显示。
enabledisplay表达式编号
*print:
打印变量或表达式的值。
print变量或表达式
表达式中有两个符号有特殊含义:
$和$$。
$表示给定序号的前一个序号,$$表示给定序号的前两个序号。
如果$和$$后面不带数字,则给定序号为当前序号。
*backtrace:
打印指定个数的栈帧(stackframe)。
backtrace栈帧个数
*frame:
打印栈帧。
frame栈帧号
*infoframe:
显示当前栈帧的详细信息。
*select-frame:
选择栈帧,选择后可以用infoframe来显示栈帧信息。
select-frame栈帧号
*kill:
结束当前程序的调试。
*quit:
退出gdb。
gdb应用举例
本节用一个实例教你一步步的用gdb调试程序.被调试的程序相当的简单,但它展示了gdb的典型应用.
下面列出了将被调试的程序.这个程序被称为greeting,它显示一个简单的问候,再用反序将它列出.
#include<
stdio.h>
main()
{
charmy_string[]="
hellothere"
;
my_print(my_string);
my_print2(my_string);
}
voidmy_print(char*string)
printf("
Thestringis%s"
string);
voidmy_print2(char*string)
char*string2;
intsize,i;
size=strlen(string);
string2=(char*)malloc(size+1);
for(i=0;
i<
size;
i++)
string2[size-i]=string[i];
string2[size+1]=`'
Thestringprintedbackwardis%s"
string2);
用下面的命令编译它:
gcc–gtest.c-otest
这个程序执行时显示如下结果:
Thestringishellothere
Thestringprintedbackwardis
输出的第一行是正确的,但第二行打印出的东西并不是我们所期望的.我们所设想的输出应该是:
Thestringprintedbackwardiserehtolleh
由于某些原因,my_print2函数没有正常工作.让我们用gdb看看问题究竟出在哪儿,先键入如下命令:
gdbgreeting
--------------------------------------------------------------------------------
注意:
记得在编译greeting程序时把调试选项打开.
如果你在输入命令时忘了把要调试的程序作为参数传给gdb,你可以在gdb提示符下用file命令来载入它:
(gdb)filegreeting
这个命令将载入greeting可执行文件就象你在gdb命令行里装入它一样.
这时你能用gdb的run命令来运行greeting了.当它在gdb里被运行后结果大约会象这样:
(gdb)run
Startingprogram:
/root/greeting
Programexitedwithcode041
这个输出和在gdb外面运行的结果一样.问题是,为什么反序打印没有工作?
为了找出症结所在,我们可以在my_print2函数的for语句后设一个断点,具体的做法是在gdb提示符下键入list命令三次,列出源代码:
(gdb)list
技巧:
在gdb提示符下按回车健将重复上一个命令.
第一次键入list命令的输出如下:
1#include<
2
3main()
4{
5charmy_string[]="
6
7my_print(my_string);
8my_print2(my_string);
9}
10
如果按下回车,gdb将再执行一次list命令,给出下列输出:
11my_print(char*string)
12{
13printf("
14}
15
16my_print2(char*string)
17{
18char*string2;
19intsize,i;
20
再按一次回车将列出greeting程序的剩余部分:
21size=strlen(string);
22string2=(char*)malloc(size+1);
23for(i=0;
24string2[size-i]=string[i];
25string2[size+1]=`'
26printf("
27}
根据列出的源程序,你能看到要设断点的地方在第24行,在gdb命令行提示符下键入如下命令设置断点:
(gdb)break24
gdb将作出如下的响应:
Breakpoint1at0x139:
filegreeting.c,line24
(gdb)
现在再键入run命令,将产生如下的输出:
Breakpoint1,my_print2(string=0xbfffdc4"
)atgreeting.c:
24
24string2[size-i]=string[i]
你能通过设置一个观察string2[size-i]变量的值的观察点来看出错误是怎样产生的,做法是键入:
(gdb)watchstring2[size-i]
gdb将作出如下回应:
Watchpoint2:
string2[size-i]
现在可以用next命令来一步步的执行for循环了:
(gdb)next
经过第一次循环后,gdb告诉我们string2[size-i]的值是`h`.gdb用如下的显示来告诉你这个信息:
Watchpoint2,string2[size-i]
Oldvalue=0`00'
Newvalue=104`h'
my_print2(string=0xbfffdc4"
)atgreeting.c:
23
23for(i=0;
i<
size;
这个值正是期望的.后来的数次循环的结果都是正确的.当i=10时,表达式string2[size-i]的值等于`e`,size-i的值等于1,最后一个字符已经拷到新串里了.
如果你再把循环执行下去,你会看到已经没有值分配给string2[0]了,而它是新串的第一个字符,因为malloc函数在分配内存时把它们初始化为空(null)字符.所以string2的第一个字符是空字符.这解释了为什么在打印string2时没有任何输出了.
现在找出了问题出在哪里,修正这个错误是很容易的.你得把代码里写入string2的第一个字符的的偏移量改为size-1而不是size.这是因为string2的大小为12,但起始偏移量是0,串内的字符从偏移量0到偏移量10,偏移量11为空字符保留.
为了使代码正常工作有很多种修改办法.一种是另设一个比串的实际大小小1的变量.这是这种解决办法的代码:
my_print(char*string)
my_print2(char*string)
intsize,size2,i;
size2=size-1;
string2[size2-i]=string[i];
string2[size]=`'
本文来自CSDN博客,转载请标明出处:
file:
///D:
/2009Linux实习/2009%20Linux%20实习/Gbd调试器/Linux%20下的%20gbd调试%20-%20tianhappy(城市旅行者)%20-%20CSDN博客.htm