1、GDB是什么东西
可以看官方文档
翻译过来就是:
GDB,GNU项目调试器允许您查看另一个程序在执行时“内部”发生了什么,或者另一程序在崩溃时正在做什么。
GDB可以做四种主要的事情(加上其他支持这些事情的事情)来帮助您在行动中捕捉错误:
- 启动程序,指定任何可能影响其行为的内容。
- 使程序在指定条件下停止。
- 当程序停止时,请检查发生了什么。
- 更改程序中的内容,这样您就可以尝试纠正一个错误的影响,然后继续了解另一个错误。
这些程序可能与GDB(本地)在同一台机器上执行,也可能在另一台机器(远程)上执行,或者在模拟器上执行。GDB可以在最流行的UNIX和Microsoft Windows变体上运行,也可以在Mac OS X上运行。
2、GDB支持哪些语言
GDB supports the following languages (in alphabetical order):
- Ada
- Assembly汇编语言
- C
- C++
- D
- Fortran
- Go
- Objective-C
- OpenCL
- Modula-2
- Pascal 结构化语言
- Rust
语言分为:
机器语言(01001)
汇编语言 (ADD)
编程语言(B语言-》C语言)
3、安装GDB
方法一:直接 install
apt-get install gdb
//下载完成可以用查看版本号来检验是否下载成功
gdb --version
方法二:利用 Linux 内部的命令行进行网上下载
1. wget http://ftp.gnu.org/gnu/gdb/gdb-8.1.1.tar.gz
2. tar -zxvf gdb-8.1.1.tar.gz
3. cd gdb-8.1.1
4. ./configure
5. make
6. make install
4、GDB基本命令
4.1 启动 gdb
编写一段简单的代码 test.c
#include<stdio.h>
int main()
{
int arr[4] = {1, 2, 3, 4};
int i = 0;
for(i; i<4; i++)
{
printf("%d\n", arr[i]);
}
return 0;
}
- 生存 debug 版本的可执行程序
gcc -o test test.c -g
或
gcc test.c -o test -g
如果gcc的时候没有给生成的可执行文件命名,就比如上面的test,系统就会自动生成一个默认的叫 a.out 的可执行文件
注意:所有的调试代码操作必须在 debug 版本下运行
使用下面的命令可以查看调试信息:
readelf -S test | grep debug
- 启动 GDB
命令如下:
gdb test
gdb -q test //表示不打印gdb版本信息,界面较为干净
4.2 list 查看源码
- list,也可以简写为‘l’
查看源程序代码,默认显示 10 行,按回车键继续看余下的代码。
4.3 run 运行程序
- run,可简写为‘r’
运行程序直到遇到结束或者遇到断点等待下一个命令。
4.4 quit 退出gdb模式
- quit,也可以简写为‘q’
退出gdb 模式
4.5 break 设置断点
- break,也可以简写为‘b’
(1)在哪里设置断点,可以用
break + 函数名/行号
(2)显示断点信息
info break/b
Num: 断点编号
Disp:断点执行一次之后是否有效 keep:有效 dis:无效
Enb: 当前断点是否有效 y:有效 n:无效
Address:内存地址
What:位置
4.6 next 单步执行
- next(n)
向前执行一步,当遇到函数调用时,不会进入被调用函数中
4.7 step 单步执行
- step(s)
单步调试如果有函数调用,则进入函数,与命令 n 不同,n 是不进入调用函数的。
程序如下test1.c
#include<stdio.h>
void hello()
{
printf("hello echo~\n");
}
int main()
{
int arr[4] = {1, 2, 3, 4};
int i = 0;
for(i; i<4; i++)
{
printf("%d\n", arr[i]);
}
hello();
return 0;
}
4.8 print查看变量的信息
- print(p)
print + 表达式:简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,
那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。
print a:将显示整数 a 的值
print ++a:将把 a 中的值加1,并显示出来
print name:将显示字符串 name 的值
print gdb_test(22):将以整数22作为参数调用 gdb_test() 函数
print gdb_test(a):将以变量 a 作为参数调用 gdb_test() 函数
5、GDB小技巧
5.1 使用shell命令
在 gdb 里可以通过 shell 去调用终端的命令
5.2 日志功能
- 开启日志
set logging on
5.3 watchpoint观察点
当我们想要观察一个变量是否变化,对你程序带来的影响的时候,可以使用 watchpoint。
info watchpoints:查看 watchpoints
6、调式 core 文件
程序调试-》程序挂掉的文件-》core调式一个挂掉的程序
测试程序 test_error.c
#include<stdio.h>
int main()
{
int *temp = NULL;
*temp = 10;
return 0;
}
一个电脑或者主机,它是多人共享的,会对当前的shell或者用户做一些限制,core 文件比较大,不会默认生成,想要去调资源的一些设置。
资源的设置用 ulimit
ulimit -a:查看当前资源有哪些限制
core file size 就是 core 文件的大小,默认是 0,所以它肯定不会自动生成,我们就需要去改 core file size。
6.1 开启 core 文件
ulimit -c unlimited
注意:如果此时还没有出现 core 文件,需要改一下路径即可:
echo "/corefile/core-%e-%p-%t" > core_pattern
此时,我们可以再编译一下那个出错的文件:
可以看到出现了 core 文件
出现了 core 文件之后,可以进行 gdb 调试了。
gdb 二进制文件 core文件
6.2 如何调试正在运行的程序
(1)写一个 test_for.c 程序
(2)gcc 编译
gcc -g test_for.c
./a.out & (让其后台运行)
(3)gdb 调试
gdb -p 进程pid