日期:2014-05-16  浏览次数:20430 次

一步一步学调试(一)——gdb命令小结

之前想验证一些关于堆栈的问题,但是没什么好方法,printf实在局限,流于表面,只间表象(值、范围、规律)不见真身(地址、寄存器、过程),所以想到了gdb——一个强大的调试工具,还能看汇编代码,现在先把这两天学的常用的命令做一个小结,以后有用到的可能再来更新一下:


括号内为全称补全,缩写全称均可用。

例:(e)x(amine)表示既可以用x又可以用examine

(gdb)代表gdb环境命令行提示符。

关于缩写,非常类似Linux的shell中的tab功能,但是与shell不同的是有默认选择:

你不一定要写全,也不一定只写首字母,比如(gdb) layout 命令,如果写个l,那么缺省的是list,抢不过,写layout——又太麻烦,你只要写上la、lay、layo都行,抢不上槽没关系,只要有一点不同,就默认是你了。


1.进入gdb:

#gdb test -q(uiet)

其中test为目标可执行文件,-q代表不打印那一大串版本版权信息之类的刷屏字幕。

这里有个小常识就是用gcc编译目标文件test时,记得-g,表示可调试。

另外,直接进入gdb而未加载可执行文件,或者加载了目标文件,想换一个其他的——可以使用

(gdb)file test2

或者

(gdb)exec(-file) test2

2.断点的设立:

(gdb)b(reakpoints) <rowNums...>

<rowNums...>代表想要设立断点的行数

忘了哪行是什么?没关系,你可以用list

(gdb) list
1	#include<stdio.h>
2	int main()
3	{
4		int i = 10;
5		i = 11;
6		printf("the address of i is %p and the value of i is %d\n",&i,i);
7	}
8	

另外,list也可以设置显示行数和指定位置的

(gdb)list

(gdb)list 10

(gdb)list 5,10

(gdb)func

比如默认显示10行,可以指定第5到第10行,指定显示某函数代码,等等。

不过最好的建议还是开俩终端,一边看代码,一边调试,看着舒服。

另外

(gdb) layout

也可以显示程序代码,还是用框子圈起来的,高大上。


(gdb)b func

(gdb)b *func

在函数func()设立断点,星号代表进入前,插结果——一目了然~!

(gdb) b *main
Breakpoint 1 at 0x80483e4: file testPC.c, line 3.
(gdb) b main
Breakpoint 2 at 0x80483ed: file testPC.c, line 4.
(gdb) info b
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080483e4 in main at testPC.c:3
2       breakpoint     keep y   0x080483ed in main at testPC.c:4
其中

(gdb)info b(reakpoints)

相当于列表打印所有已设立的断点。有了断点,当然也可以删掉断点,看到列表中左边的”Num“了么,用得上:

(gdb) d 1
(gdb) info b
Num     Type           Disp Enb Address    What
2       breakpoint     keep y   0x080483ed in main at testPC.c:4
(gdb) 
(gdb)d(elete) Num

代表删除第Num个断点。可以看到第一个断点被删了。

3.基本调试流程

有了断点,就该用上了。

第一步,开始运行程序:

(gdb)r(un)


(gdb)n(ext)


(gdb)s(tep)


和其他调试相仿,这两条分别代表step over和step in,


(gdb)c(ontinue)

run和continue功能其实差不多,都是继续往下运行,直到下一个断点停下来,不过场合不一样罢了:run是开始运行前的启动命令,continue是运行中的命令。



4.汇编style: