2008-8-9 23:36
charles
UNIX系统开发-gdb调试技术
GNU的调试器称为gdb,该程序是一个交互式工具,工作在字符模式。在 X Window 系统中,有一个gdb的前端图形工具,称为xxgdb。gdb 是功能强大的调试程序,可完成如下的调试任务: 4h7_SEQv
* 设置断点; $Fj/G#sW*k[$s)o+\
* 监视程序变量的值; c,QJ$s
C7U
* 程序的单步执行;
#hO;B0y:{U#]1t
* 修改变量的值。
;Kr"B%_:Q!F&`gD
在可以使用 gdb 调试程序之前,必须使用 -g 选项编译源文件。可在 makefile 中如下定义 CFLAGS 变量:
i0USr0VP.B
CFLAGS = -g Lfcmq
运行 gdb 调试程序时通常使用如下的命令: +H d.S F|5hs
gdb progname
9N:W!_O_2vn
2[ \vz!kt|fy
在 gdb 提示符处键入help,将列出命令的分类,主要的分类有: 4z+K'[C*~dV
QK
* aliases:命令别名
2`YA-Z%N.r
* breakpoints:断点定义; ?XGH[:[XD&f0s
* data:数据查看;
,c1ws;B?z6I(eZ
e2b
* files:指定并查看文件;
)L8XIgq
cE
* internals:维护命令;
{V#g4iw
* running:程序执行; q{W3C*c6K!J
* stack:调用栈查看;
4XJ"BQh2wq*b6\
* statu:状态查看; bB8Ii&X#H%v
* tracepoints:跟踪程序执行。 I8v^W8Bo2IwI
键入 help 后跟命令的分类名,可获得该类命令的详细清单。 s&PX0CP
Rb
J
GFsXjL
!?lek~5lR
gdb 的常用命令 yQ!qZ5X E%cB]
qUJ-d:i$y{
WakL@v;Q#QUdh
命令 解释 wf8o}7Dyh
break NUM 在指定的行上设置断点。 #Z PtYO{
bt 显示所有的调用栈帧。该命令可用来显示函数的调用顺序。
7lyMH6O(z4U
clear 删除设置在特定源文件、特定行上的断点。其用法为clear FILENAME:NUM
&u!WH'S?
continue 继续执行正在调试的程序。该命令用在程序由于处理信号或断点而 导致停止运行时。 gNu3^q_;MF
display EXPR 每次程序停止后显示表达式的值。表达式由程序定义的变量组成。
*q T`|v6Q
file FILE 装载指定的可执行文件进行调试。
h2f?RWV.v
help NAME 显示指定命令的帮助信息。
;ud^^g
info break 显示当前断点清单,包括到达断点处的次数等。
vTD]%A6W,ax
info files 显示被调试文件的详细信息。
;bC5}p#A.Is4v
\
info func 显示所有的函数名称。
4X/]"d qt+SjB8J-O
v
info local 显示当函数中的局部变量信息。
p;BDZt9L8\
info prog 显示被调试程序的执行状态。
e]
Z'W,|3M(y
info var 显示所有的全局和静态变量名称。 CymT*p+CR#M
kill 终止正被调试的程序。 '[!RCq |
list 显示源代码段。 R].~
s6Op
make 在不退出 gdb 的情况下运行 make 工具。 +@5S X(jQL U~
next 在不单步执行进入其他函数的情况下,向前执行一行源代码。
~2G~9Y"K
print EXPR 显示表达式 EXPR 的值。
2008-8-9 23:36
charles
******gdb 使用范例************************ wV7xw0S^3^a
----------------- %oHI3E4hk"\G
清单 一个有错误的 C 源程序 bugging.c 6b
kO+a4E
代码:
!H J,Z|t:O m3]
8]L[?psfM7],h:Y#a
----------------- !Mod~A
1 #include <unistd.h>;
vln&U`;Z,h
2
X_5s.Hc$T9V{
3 static char buff [256]; [2w |OSRi
4 static char* string;
*pW9` Vu
5 int main ()
b1m5|y UFa"N
6 {
0Rk)f XC1t#V
7 printf ("lease input a string: ";
RBNj Cr4a
8 gets (string);
bG
ToKvy ?9]
9 printf ("\nYour string is: %s\n", string);
YKEq|J.z
10 } d%P2g^
?
9h`xwD1sAsdZG
zo0?Q2z
U7oS
-----------------
KM5PvMzY
~,Q
上面这个程序非常简单,其目的是接受用户的输入,然后将用户的输入打印出来。该程序使用了一个未经过初始化的字符串地址 string,因此,编译并运行之后,将出现 Segment Fault 错误: M/O4K9Z"w_-WxJa
$ gcc -o bugging -g bugging.c |5LS;M^pci
$ ./bugging (Z:O"I H"{I,M
Please input a string: asfd X!aQ"x$WPE`kf
\
Segmentation fault (core dumped)
T$P&UTs"N
为了查找该程序中出现的问题,我们利用 gdb,并按如下的步骤进行: Jf"s~.we P
1.运行 gdb bugging 命令,装入 bugging 可执行文件;
UCgf&pN
2.执行装入的 bugging 命令 run;
X8K+t8^'cYA:Y;c
q
3.使用 where 命令查看程序出错的地方;
i/u0Y
}:T(tar1M
4.利用 list 命令查看调用 gets 函数附近的代码; s(PG|UD*S1l
5.唯一能够导致 gets 函数出错的因素就是变量 string。用print命令查看 string 的值; (c*^;E5X:Iz|HO4i,Yd
6.在 gdb 中,我们可以直接修改变量的值,只要将 string 取一个合法的指针值就可以了,为此,我们在第8行处设置断点 break 8; t*J"Z;g;Sb
7.程序重新运行到第 8行处停止,这时,我们可以用 set variable 命令修改 string 的取值;
;S'``(eGL$[
yR
8.然后继续运行,将看到正确的程序运行结果。