GDB, the GNU Project debugger —— gdb官网
gdb 是一款调试器,能打断点。支持多种语言,例如 c、c++、go。 Tip:有关 GNU Project,请看本篇扩展。
官网显示最新版本是13.2(20230704)。点击官网顶部[documentation]可查看文档。
安装GDB
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.
复制代码
最常用命令
man gdb 告诉我们最常用的命令有:break、run、print、c、next、list、step、quit。
// 以下是一些最常用的GDB命令:
Here are some of the most frequently needed GDB commands:
break [file:]function
Set a breakpoint at function (in file).
run [arglist]
Start your program (with arglist, if specified).
bt Backtrace: display the program stack.
print expr
// 显示表达式的值
Display the value of an expression.
c Continue running your program (after stopping, e.g. at a breakpoint).
next
// 执行下一条程序语句(在停止后);跳过该行中的任何函数调用。
Execute next program line (after stopping); step over any function calls in the line.
edit [file:]function
look at the program line where it is presently stopped.
list [file:]function
type the text of the program in the vicinity of where it is presently stopped.
step
Execute next program line (after stopping); step into any function calls in the line.
help [name]
Show information about GDB command name, or general information about using GDB.
quit
Exit from GDB.
复制代码
准备一段 C 代码用作gdb命令学习:
#include <stdio.h>
// add 函数
int add(int a, int b) {
int sum = a + b;
return sum;
}
int main() {
int num1 = 3;
int num2 = 5;
int result = add(num1, num2);
printf("两个整数的和为:%d\n", result);
return 0;
}
复制代码
run 和 quit
通过 gdb demo 运行进入gdb模式,输入 run 运行程序,输入 quit 则退出gdb。详细请看:
// 通过 -g 编译出有调试信息的可执行文件
jjj-pc:~/pj$ gcc demo.c -o demo -g
// gdb 运行
jjj-pc:~/pj$ gdb demo
GNU gdb (Ubuntu 9.1-0kylin1) 9.1
Copyright (C) 2020 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from demo...
// 输入 run 运行程序
(gdb) run
Starting program: /home/jjj/pj/demo
两个整数的和为:8
[Inferior 1 (process 3022770) exited normally]
// 输入 quit 退出
(gdb) quit
jjj-pc:~/pj$
复制代码
Tip: ctrl + z 能直接退出gdb
list
如果不知道在哪行或哪个方法打断点,可以通过 list 查看源码。请看示例:
jjj-pc:~/pj$ gdb demo
GNU gdb (Ubuntu 9.1-0kylin1) 9.1
Copyright (C) 2020 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from demo...
// 查看源码
(gdb) list
1 #include <stdio.h>
2
3 // 自定义函数,用于计算两个整数的和
4 int add(int a, int b) { // a, b 叫形参
5 int sum = a + b;
6 return sum;
7 }
8
9 int main() {
10 int num1 = 3;
// 一次显示不完,继续查看后面10行
(gdb) list
11 int num2 = 5;
12
13 // 调用自定义函数计算两个整数的和
14 int result = add(num1, num2);
15
16 printf("两个整数的和为:%d\n", result);
17
18 return 0;
19 }
// 到底了。
(gdb) list
Line number 20 out of range; demo.c has 19 lines.
// 查看5到10行
(gdb) list 5,10
5 int sum = a + b;
6 return sum;
7 }
8
9 int main() {
10 int num1 = 3;
(gdb)
复制代码
break 和 info break
break(简写 b) 用于打断点,info break 用于查看打了哪些断点。请看示例:
jjj-pc:~/pj$ gdb demo
GNU gdb (Ubuntu 9.1-0kylin1) 9.1
Copyright (C) 2020 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from demo...
// 给 mian 方法打断点
(gdb) break main
Breakpoint 1 at 0x1167: file demo.c, line 9.
// 给11行打断点
(gdb) b 11
Breakpoint 2 at 0x117a: file demo.c, line 11.
// 查看打了哪些断点
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000001167 in main at demo.c:9
2 breakpoint keep y 0x000000000000117a in main at demo.c:11
// 查看打了哪些断点
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000001167 in main at demo.c:9
2 breakpoint keep y 0x000000000000117a in main at demo.c:11
复制代码
next 和 step
代码中断后,输入 next 和 step 都会执行下一行,然而 next 会跳过函数,step 会进入函数。请看示例:
next 跳过函数
Type "apropos word" to search for commands related to "word"...
Reading symbols from demo...
// 打断点
(gdb) b 9
Breakpoint 1 at 0x1167: file demo.c, line 9.
// 运行
(gdb) run
Starting program: /home/jjj/pj/demo
// 在断点处停止
Breakpoint 1, main () at demo.c:9
9 int main() {
// 下一行
(gdb) next
10 int num1 = 3;
(gdb) next
// 下一行
11 int num2 = 5;
(gdb) next
// 下一行。跳过函数
14 int result = add(num1, num2);
(gdb) next
// 下一行
16 printf("两个整数的和为:%d\n", result);
(gdb) next
两个整数的和为:8
18 return 0;
复制代码
step 进入函数
Type "apropos word" to search for commands related to "word"...
Reading symbols from demo...
(gdb) b 9
Breakpoint 1 at 0x1167: file demo.c, line 9.
(gdb) run
Starting program: /home/jjj/pj/demo
Breakpoint 1, main () at demo.c:9
9 int main() {
(gdb) step
10 int num1 = 3;
(gdb) step
11 int num2 = 5;
(gdb) step
14 int result = add(num1, num2);
(gdb) step
add (a=21845, b=1431654909) at demo.c:4
4 int add(int a, int b) {
(gdb) step
5 int sum = a + b;
(gdb) step
6 return sum;
(gdb) step
7 }
(gdb) step
main () at demo.c:16
16 printf("两个整数的和为:%d\n", result);
(gdb) step
两个整数的和为:8
18 return 0;
复制代码
continue
next 和 step 会执行下一行,而continue(简写c) 会执行到下一个断点处停止。 请看示例:
Type "apropos word" to search for commands related to "word"...
Reading symbols from demo...
// 断点
(gdb) b main
Breakpoint 1 at 0x1167: file demo.c, line 9.
// 断点
(gdb) b 16
Breakpoint 2 at 0x1193: file demo.c, line 16.
// 运行后在第一断点处停止
(gdb) run
Starting program: /home/jjj/pj/demo
Breakpoint 1, main () at demo.c:9
9 int main() {
// 下一个断点
(gdb) c
Continuing.
Breakpoint 2, main () at demo.c:16
16 printf("两个整数的和为:%d\n", result);
(gdb)
复制代码
print
print 用于查看表达式的值。请看示例:
// 在11行打断点,查看 num1
(gdb) list 9,11
9 int main() {
10 int num1 = 3;
11 int num2 = 5;
(gdb) b 11
Breakpoint 1 at 0x117a: file demo.c, line 11.
(gdb) run
Starting program: /home/jjj/pj/demo
Breakpoint 1, main () at demo.c:11
11 int num2 = 5;
// 查看num1的值
(gdb) print num1
$1 = 3
// 查看num1的地址
(gdb) print &num1
$2 = (int *) 0x7fffffffe2c4
复制代码
gdb 小技巧
shell
gdb 可以执行 shell 命令。请看示例:
[code]Type "apropos word" to search for commands related to "word"...Reading symbols from demo2...// ll 命令没有(gdb) shell llbash: ll:未找到命令// 执行 ls 命令(gdb) shell lsdemo2 demo2.c// 执行 cat 命令(gdb) shell cat demo2.c#include int main() { int i; for (i = 1; i