Appearance
以下内容摘自官网 GDB:GNU 工程调试器 (sourceware.org)
什么是GDB?
GDB,GNU工程调试器,允许你看到发生了什么在另一个程序执行时“内部”它 - 或者另一个程序 在它崩溃的那一刻正在做。
GDB 可以做四种主要的事情(加上支持中的其他事情 其中)帮助您捕获行为中的错误:
- 启动程序,指定可能影响其行为的任何内容。
- 使程序在指定条件下停止。
- 检查程序停止时发生的情况。
- 更改程序中的内容,以便您可以试验 纠正一个错误的影响,并继续了解另一个错误。
这些程序可能与 GDB(本机)在同一台计算机上执行, 在另一台计算机(远程)或模拟器上。GDB 可以在大多数上运行 流行的UNIX和Microsoft Windows变体,以及Mac OS X。
GDB 支持的语言 ?
- Ada
- Assembly
- C
- C++
- D
- Fortran
- Go
- Objective-C
- OpenCL
- Modula-2
- Pascal
- Rust
安装GDB
bash
# ubuntu
$ sudo apt install gdb
# check
$ gdb --version
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 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.QuickStart
c
#include <stdio.h>
int main()
{
int arr[4] = {1,2,3,4};
int i = 0;
for(i = 0; i < 4; i++) {
printf("%d\n", arr[i]);
}
return 0;
}编译 :
bash
gcc -g test.c生成的文件也是 a.out , 但可以通过 gdb 执行 :
bash
$ gdb a.out
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...
(gdb)可以看到 prompt 变成了 (gbd) , 先运行下 run 吧 ( 可以缩写成 r) :
bash
(gdb) run
Starting program: /home/ubuntu/ccc/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
1
2
3
4
[Inferior 1 (process 267601) exited normally]
(gdb)程序直接执行完了, 输入 quit 退出.
指令
常用的几个 GDB 指令可以通过 man gbd 进行查看:
break [file:][function|line]
Set a breakpoint at function or line (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
Exit from GDB.break
打断点, 后面可以跟函数名和行数
bash
(gdb) b 9
Breakpoint 1 at 0x11b0: file testgdb.c, line 9.
(gdb) b main
Breakpoint 2 at 0x1175: file testgdb.c, line 4.此时, 运行 r, 程序会在 main 暂停
bash
(gdb) r
Starting program: /home/ubuntu/ccc/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 2, main () at testgdb.c:4
4 {next
如果想要继续执行, 输入 next :
bash
(gdb) n
5 int arr[4] = {1,2,3,4};程序向下执行了 1 行
info
要查看已经打的断点:
bash
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000000011b0 in main at testgdb.c:9
2 breakpoint keep y 0x0000000000001175 in main at testgdb.c:4当然, info 支持查看其他内容
list
查看源代码, 方便断点:
bash
(gdb) list
1 #include <stdio.h>
2
3 int main()
4 {
5 int arr[4] = {1,2,3,4};
6 int i = 0;
7 for(i = 0; i < 4; i++)
8 {
9 printf("%d\n", arr[i]);
10 }print
断点的主要目的就是在断点处查看变量的值, 用 print 指令:
bash
(gdb) p arr[1]
$1 = 2step
进入当前行的函数调试, 一般是直接返回了
shell
在 GDB 中, 可以直接调用终端的指令:
bash
(gdb) shell ls
a.out testgdb.cwatch
观察地址内容的变化, 变量内部的变化
bash
(gdb) print &i
$2 = (int *) 0x7fffffffe1fc
(gdb) watch *0x7fffffffe1fc
Hardware watchpoint 2: *0x7fffffffe1fc
(gdb) info watchpoint
Num Type Disp Enb Address What
2 hw watchpoint keep y *0x7fffffffe1fc
(gdb) n
Hardware watchpoint 2: *0x7fffffffe1fc
Old value = 0
New value = 1
0x00005555555551d3 in main () at testgdb.c:7
7 for(i = 0; i < 4; i++)当程序不断执行下去的时候, 只要 watchpoint 的内容变化了, 会直接打印 old/new value.
开启日志
记录调试的过程
bash
(gbd) set logging on
Copying output to gdb.txt调试错误退出 Core 文件
如下代码:
c
#include <stdio.h>
int main()
{
int *tmp = NULL;
*tmp = 10;
return 0;
}编译 & 运行:
bash
$ gcc -g test.c
$ ./a.out
Segmentation fault (core dumped)产生段错误, 并生成 core 文件 : ( 无法生成 Core 文件: Core dumped, but core file is not in the current directory? )
bash
$ ls
ubuntu@ubuntu:~/ccc$ ls
a.out core.269685 test.c用 GDB 查看错误在什么地方 :
bash
$ gbd a.out core.269685
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...
[New LWP 269685]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055bcffe0013d in main () at err.c:6
6 *tmp = 10;可以看到是代码第六行出现了错误.