用 gdb 调试 GCC 程序.docx
- 文档编号:5500678
- 上传时间:2022-12-17
- 格式:DOCX
- 页数:10
- 大小:19.44KB
用 gdb 调试 GCC 程序.docx
《用 gdb 调试 GCC 程序.docx》由会员分享,可在线阅读,更多相关《用 gdb 调试 GCC 程序.docx(10页珍藏版)》请在冰豆网上搜索。
用gdb调试GCC程序
用gdb调试GCC程序
Linux中包含有一个很有用的调试工具--gdb(GNUDebuger),它可以用来调试C和C++程序,功能不亚于Windows下的许多图形界面的调试工具。
和所有常用的调试工具一样,gdb提供了以下功能:
#监视程序中变量的值
#在程序中设置断点
#程序的单步执行
在使用gdb前,必须先载入可执行文件,因为要进行调试,文件中就必须包含调试信息,所以在用gcc或cc编译时就需要用-g参数来打开程序的调试选项。
调试开始时,必须先载入要进行调试的程序,可以用以下两种方式:
*在启动gdb后执行以下命令:
file可执行文件路径
*在gdb启动时就载入程序:
gdb可执行文件路径
载入程序后,接下来就是要进行断点的设置,要监视的变量的添加等工作,下面对在这个过程中常会用到的命令逐一进行介绍:
基本gdb命令.
file装入想要调试的可执行文件.
kill终止正在调试的程序.
list列出产生执行文件的源代码的一部分.
next执行一行源代码但不进入函数内部.
step执行一行源代码而且进入函数内部.
run执行当前被调试的程序
quit终止gdb
watch使你能监视一个变量的值而不管它何时被改变.
break在代码里设置断点,这将使程序执行到这里时被挂起.
make使你能不退出gdb就可以重新产生可执行文件.
shell使你能不离开gdb就执行UNIXshell命令.
命令详解
*list:
显示程序中的代码,常用使用格式有:
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
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 string2[size-i]=string[i]; string2[size+1]=`'; printf("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 Thestringishellothere Thestringprintedbackwardis Programexitedwithcode041 这个输出和在gdb外面运行的结果一样.问题是,为什么反序打印没有工作? 为了找出症结所在,我们可以在my_print2函数的for语句后设一个断点,具体的做法是在gdb提示符下键入list命令三次,列出源代码: (gdb)list (gdb)list (gdb)list -------------------------------------------------------------------------------- 技巧: 在gdb提示符下按回车健将重复上一个命令. -------------------------------------------------------------------------------- 第一次键入list命令的输出如下: 1#include 2 3main() 4{ 5charmy_string[]="hellothere"; 6 7my_print(my_string); 8my_print2(my_string); 9} 10 如果按下回车,gdb将再执行一次list命令,给出下列输出: 11my_print(char*string) 12{ 13printf("Thestringis%s",string); 14} 15 16my_print2(char*string) 17{ 18char*string2; 19intsize,i; 20 再按一次回车将列出greeting程序的剩余部分: 21size=strlen(string); 22string2=(char*)malloc(size+1); 23for(i=0;i 24string2[size-i]=string[i]; 25string2[size+1]=`'; 26printf("Thestringprintedbackwardis%s",string2); 27} 根据列出的源程序,你能看到要设断点的地方在第24行,在gdb命令行提示符下键入如下命令设置断点: (gdb)break24 gdb将作出如下的响应: Breakpoint1at0x139: filegreeting.c,line24 (gdb) 现在再键入run命令,将产生如下的输出: Startingprogram: /root/greeting Thestringishellothere Breakpoint1,my_print2(string=0xbfffdc4"hellothere")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"hellothere")atgreeting.c: 23 23for(i=0;i 这个值正是期望的.后来的数次循环的结果都是正确的.当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的变量.这是这种解决办法的代码: #include main() { charmy_string[]="hellothere"; my_print(my_string); my_print2(my_string); } my_print(char*string) { printf("Thestringis%s",string); } my_print2(char*string) { char*string2; intsize,size2,i; size=strlen(string); size2=size-1; string2=(char*)malloc(size+1); for(i=0;i string2[size2-i]=string[i]; string2[size]=`'; printf("Thestringprintedbackwardis%s",string2); } 本文来自CSDN博客,转载请标明出处: file: ///D: /2009Linux实习/2009%20Linux%20实习/Gbd调试器/Linux%20下的%20gbd调试%20-%20tianhappy(城市旅行者)%20-%20CSDN博客.htm
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- gdb 调试 GCC 程序