gdb是什么?在linux终端找man后,对gdb的描述如下——
/**********gdb**********/
gdb即The
GNU Debugger的缩写。
gdb是一种调试工具,使用gdb可以窥探一个程序在运行时或者crash时的内部信息,主要有以下四种功能:
1、启动程序,按自定义的方式运行程序。
2、在特定条件下(即断点处)stop程序。
3、程序stop时,检查程序中所发生的事情。
4、改变程序执行环境,修正bug行为。
gdb可以调试C/C++程序,如果GNU提供了Fortran编译器的话,也可以调试Fortran程序。在shell终端启动gdb有多种方式,如下:
1、直接运行gdb而不带任何参数
$ gdb
GNU gdb (GDB) 7.5.91.20130417-cvs-ubuntu
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "showcopying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb)
2、带参数运行gdb的几种形式
$ gdb program
$ gdb program core
$ gdb program pid
program是可执行文件,core是程序非法执行时coredump产生的文件,对于服务程序可指定pid,这时gdb会自动attach上去。
下面是几个常用的gdb命令:
break [file:]function
在(file文件的)function函数上设置断点。
run [arglist]
运行程序(可以指定运行参数arglist)。
bt
即backtrace,显示程序栈信息。
print expr
显示expr表达式的值。
c
即continue,继续执行程序,例如程序停在某个断点之后。
next
程序停止后执行程序下一行,会跳过function。
edit [file:]function
在程序当前停止的地方查看程序行。
list [file:]function
打印程序当前停止地方附近的文本。
step
程序停止后执行程序下一行,会进入function。
help[name]
显示提示信息,name是某个gdb命令。
quit
推出gdb。
/**********gdb**********/
下面以一个具体的例子main.c作为示例。
// main.c #include <stdio.h> int sum(int n) { int ret = 0; int i = 0; for (i = 1; i <= n; ++i) { ret += i; } return ret; } int main(void) { int n = 10; int result = sum(n); printf("result = %d\n", result); return 0; }
在linux终端编译main.c生成可执行文件test,-g生成调试信息,-o制定可执行文件名:
$ gcc -g main.c -o test
用gdb启动test:
$ gdb test
用list(缩写为l)显示sum函数的完整信息:
(gdb) list sum
1 // main.c
2 #include <stdio.h>
3
4 int sum(int n)
5 {
6 int ret = 0;
7 int i = 0;
8 for (i = 1; i <= n; ++i) {
9 ret += i;
10 }
按回车键继续:
(gdb)
11 return ret;
12 }
13
14 int main(void)
15 {
16 int n = 10;
17 int result = sum(n);
18 printf("result = %d\n", result);
19
20 return 0;
按回车键继续:
(gdb)
21 }
22
结束,再次按回车键会提示越界:
(gdb)
Line number 23 out of range; main.c has 22 lines.
用break(缩写为b)在程序第16行打断点:
(gdb) break 16
Breakpoint 1 at 0x400551: file main.c, line 16.
用b在程序sum函数处打断点:
(gdb) b sum
Breakpoint 2 at 0x40051b: file main.c, line 6.
用info(缩写为i)查看break断点信息:
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000400551 in main at main.c:16
2 breakpoint keep y 0x000000000040051b in sum at main.c:6
用run(缩写为r)执行程序(停在了断点处):
(gdb) run
Starting program: /home/test
Breakpoint1, main () at main.c:16
16 int n = 10;
用backtrace(缩写为bt)查看函数栈:
(gdb) backtrace
#0 main () at main.c:16
用next(缩写为n)执行程序下一行:
(gdb) next
17 int result = sum(n);
用n执行程序下一行(又停在了断点处):
(gdb) n
Breakpoint 2, sum (n=10) at main.c:6
6 int ret = 0;
用n执行程序下一行:
(gdb) n
7 int i = 0;
用n执行程序下一行:
(gdb) n
8 for (i = 1; i <= n; ++i) {
用n执行程序下一行:
(gdb) n
9 ret += i;
用print(缩写为p)打印某个变量的值:
(gdb) print ret
$1 = 1
用n执行程序下一行(从9行返回到了8行):
(gdb) n
8 for (i = 1; i <= n; ++i) {
用continue(缩写为c)继续运行程序(直到下一个断点或者程序结束):
(gdb) continue
Continuing.
result = 55
[Inferior 1 (process 5540) exited normally]
如果没执行上面的continue命令,通过finish可结束当前函数:
(gdb) finish
Run till exit from #0 sum (n=10) at main.c:9
0x0000000000400562 in main () at main.c:17
17 int result = sum(n);
Value returned is $2 = 55
用quit(缩写为q)退出gdb:
(gdb) quit