概述
GDB是GNU发布的一个调试工具。gdb 是基于UNIX/Linux 命令行的,功能强大,可与windows平台的visual studio 媲美。
基本命令
GDB的命令非常多,但我们只要掌握几个常见的,就可以满足日常基本程序的调试需求。
命令 | 解释 | 示例 |
---|---|---|
file <文件名> | 加载被调试的可执行文件 如果执行gdb与被调试的程序不在同个目录,则需要带上路径 |
(gdb) file gdb_sample |
l <行号> | List 的缩写,打印源码 在gcc/g++ 编译程序时,需要加上-g 选项 |
(gdb) l 1 |
r | Run 的缩写,运行程序 | (gdb) r |
c | Continue 的缩写,继续执行程序,直到下一个断点或程序结束 | (gdb) c |
b <行号> b <函数名称> |
Breakpoint 的缩写,设置断点 | (gdb) b 8 (gdb) b main |
d <断点编号> | Delete 的缩写,删除断点 | (gdb) d 2 |
s | Step Into (单步跟踪进入) 执行一行源程序代码,如果此行代码有函数调用,则进入该函数 |
(gdb) s |
n | Step Over (单步跟踪) 执行一行源程序代码,如果此行代码有函数调用,也一并执行 |
(gdb) n |
p <变量名称> | Print 的缩写, 打印变量的值 | (gdb) p i |
bt | Backtrace 的缩写,查看堆栈信息 | (gdb) bt |
q | Quit 的缩写,退出gdb 调试环境 | (gdb) q |
help <命令名称> | 可以查看各个命令的用法 | (gdb) help r |
举例
先看一个简单的程序
#include <stdio.h>
int sum(int n)
{
int sum=0, i;
for (i=0; i<n; ++i)
{
sum+=i;
}
return sum;
}
int main(int argc, char ** argv)
{
int i=1;
++i;
int result=0;
result=sum(i);
printf("sum[%d]\n", result);
return 0;
}
将上面代码保存到 gdb_sample.c
文件,然后用 gcc 编译:
gcc gdb_sample.c -g -o gdb_sample
上面的命令,用参数 -g
将源代码信息编译到可执行文件中,如果不指定,将无法在 gdb 里面查看代码,可以看看使用 -g
和不使用,编译后可执行文件的大小:
[huanghaibin@huanghaibin 17:10:17 ] gcc gdb_sample.c -g -o gdb_sample
[huanghaibin@huanghaibin 17:19:35 ] gcc gdb_sample.c -o gdb_sample_2
[huanghaibin@huanghaibin 17:19:54 ] ll gdb_sample gdb_sample_2
-rwxrwxr-x 1 huanghaibin 8.4K 3月 9 17:19 gdb_sample_2
-rwxrwxr-x 1 huanghaibin 9.7K 3月 9 17:19 gdb_sample
可以用 gdb gdb_sample
直接进入调试环境,也可以先启动gdb
,再打开可执行文件:
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7
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 "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file gdb_sample
Reading symbols from /data1/hellerhuang/test_c/gdb_sample...done.
(gdb)
上面表示可执行文件已经加载成功,(gdb)
是gdb内部命令引导符,等待用户输入命令
下面使用l
命令来查看源码,可以指定行号,回车可以继续往下查看:
(gdb) l 1
1 /*======================================================================
2 @file gdb_sample.c
3 @brief
4 @author huanghaibin
5 @version 1.0
6 @date 2018-03-09
7 @copyright Copyright (c) 2015 Tencent Inc. All Rights Reserved.
8 ======================================================================*/
9
10 #include <stdio.h>
(gdb)
11
12 int sum(int n)
13 {
14 int sum=0, i;
15 for (i=0; i<n; ++i)
16 {
17 sum+=i;
18 }
19 return sum;
20 }
(gdb)
21
22 int main(int argc, char ** argv)
23 {
24 int i=1;
25 ++i;
26
27 int result=0;
28 result=sum(i);
29
30 printf("sum[%d]\n", result);
(gdb)
31 return 0;
32 }
33
(gdb)
下面使用r
命令执行程序,因为没有设置断点,所以程序执行到程序结束:
Starting program: /data1/hellerhuang/test_c/gdb_sample
sum[1]
[Inferior 1 (process 6401) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.tl2.2.x86_64
(gdb)
下面使用b
设置断点,在24行int i=1;
设置断点,后执行r
,再进入单步调试n s
:
(gdb) b 24
Breakpoint 1 at 0x40056d: file gdb_sample.c, line 24. // 设置断点
(gdb) r
Starting program: /data1/hellerhuang/test_c/gdb_sample
Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:24 // 程序中断在24行
24 int i=1;
(gdb) n
25 ++i;
(gdb) s
27 int result=0;
(gdb)
上面程序先执行到断点处(24行),然后单步调试,对于非函数,n
和 s
执行结果一样
下面在28行设置第二个断点,用明令c
直接运行到第二处断点,对比n
和 s
执行函数的结果:
(gdb) b 28 // 设置第二处断点
Breakpoint 2 at 0x40057f: file gdb_sample.c, line 28.
(gdb) c // 直接运行到第二个断点
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
28 result=sum(i);
(gdb) n // 执行整个函数
30 printf("sum[%d]\n", result);
(gdb) p result // 打印变量
$1 = 1
(gdb) r // 重新运行程序
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /data1/hellerhuang/test_c/gdb_sample
Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:24
24 int i=1;
(gdb) c
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
28 result=sum(i);
(gdb) s // 单步调试进入函数
sum (n=2) at gdb_sample.c:14
14 int sum=0, i;
(gdb) bt // 查看堆栈信息
#0 sum (n=2) at gdb_sample.c:14
#1 0x0000000000400589 in main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
(gdb) finish
Run till exit from #0 sum (n=2) at gdb_sample.c:14
0x0000000000400589 in main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
28 result=sum(i);
Value returned is $2 = 1
(gdb) n
30 printf("sum[%d]\n", result);
(gdb) p result
$3 = 1
(gdb) q
A debugging session is active.
Inferior 1 [process 10635] will be killed.
Quit anyway? (y or n) y
上面bt
可查看程序的堆栈信息,然后通过finish
命令执行完该函数,最后用命令q
退出调试。
网友评论