2008年8月26日星期二

使用gdb对linux程序进行调试

代码示例:
time.c

#include
main()
{
time_t the_time;
the_time=time((time_t *)0); /*调用time系统调用*/
printf(”The time is %ld\n”,the_time);
}

使用gcc进行编译,但是要加上-g的参数,-g的作用是在编译过程中,加入debug信息,gdb能够识别这些信息。
gcc -g -o time time.c

使用gdb time加载,使用run来运行,list来调出源代码。
(gdb) run
Starting program: /home/showrun/study/gdb/time_s
The time is 1197899802

Program exited with code 027.
(gdb) list
1 #include
2 main()
3 {
4 time_t the_time;
5 the_time=time((time_t *)0); /*调用time系统调用*/
6 printf(”The time is %ld\n”,the_time);
7 }
(gdb)

在gdb下,使用print命令查看变量的值:
(gdb) print the_time
No symbol “the_time” in current context.
为什么会没有the_time的值呢?是由于time程序已经运行完了。
让我们使用break命令设置一下程序的断点:

(gdb) list
1 #include
2 main()
3 {
4 time_t the_time;
5 the_time=time((time_t *)0); /*调用time系统调用*/
6 printf(”The time is %ld\n”,the_time);
7 }
(gdb) break 5 /*我们在程序的第5行设置了程序的断点*/
Note: breakpoint 1 also set at pc 0×8048219.
Breakpoint 2 at 0×8048219: file time.c, line 5.
(gdb) run
Starting program: /home/showrun/study/gdb/time_s

Breakpoint 1, main () at time.c:5
5 the_time=time((time_t *)0); /*调用time系统调用*/
(gdb) print the_time /*打印the_time变量的值,这里的值应该是指针*/
$2 = 134514848
(gdb) continue /*continue继续*/
Continuing.
The time is 1197900182
Program exited with code 027.
(gdb)

查看都设置了那些断点使用,info break
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0×08048219 in main at time.c:4
breakpoint already hit 1 time
2 breakpoint keep y 0×08048219 in main at time.c:5
breakpoint already hit 1 time

可以使用命令 ‘disable ’、’enable ’ 或 ‘delete ’ 来禁用、启用和彻底删除断点。

break也可以在函数上设置断点如,break main

要打印堆栈,发出命令 ‘bt’(’backtrace’ [回溯] 的缩写)
(gdb) bt
#0 main () at time.c:5
(gdb) frame 0
#0 main () at time.c:5
5 the_time=time((time_t *)0); /*调用time系统调用*/
(gdb) info locals
the_time = 134514848
实际上,发出 ‘info locals’ 命令时,gdb 会打印出当前帧中的局部变量,缺省情况下,这个帧中的函数就是被中断的函数(0 号帧)。

调试的一些命令已经说完了,下边是反编译使用dissamble
同样是gdb time
(gdb) disassemble main
Dump of assembler code for function main:
0×08048208 : lea 0×4(%esp),%ecx
0×0804820c : and $0xfffffff0,%esp
0×0804820f : pushl 0xfffffffc(%ecx)
0×08048212 : push %ebp
0×08048213 : mov %esp,%ebp
0×08048215 : push %ecx
0×08048216 : sub $0×24,%esp
0×08048219 : movl $0×0,(%esp)
0×08048220 : call 0×804e030

没有评论: