文章目录
- 一、gdb是什么?
- 二、使用说明
-
- [1. 安装](#1. 安装)
- [2. 注意事项](#2. 注意事项)
- [3. 常用调试指令](#3. 常用调试指令)
-
- [3.1 gdb](#3.1 gdb)
- [3.2 l](#3.2 l)
- [3.3 r](#3.3 r)
- [3.4 n](#3.4 n)
- [3.5 s](#3.5 s)
- [3.6 b](#3.6 b)
- [3.7 info b](#3.7 info b)
- [3.8 finish](#3.8 finish)
- [3.9 p](#3.9 p)
- [3.10 set var](#3.10 set var)
- [3.11 c](#3.11 c)
- [3.12 d breakpoints](#3.12 d breakpoints)
- [3.13 d n](#3.13 d n)
- [3.14 disable/enable breakpoints](#3.14 disable/enable breakpoints)
- [3.15 disable/enable n](#3.15 disable/enable n)
- [3.16 info b](#3.16 info b)
- [3.17 display 变量名/undisplay 编号](#3.17 display 变量名/undisplay 编号)
- [3.18 until n](#3.18 until n)
- [3.19 bt](#3.19 bt)
- [3.20 ctrl + d/quit](#3.20 ctrl + d/quit)
一、gdb是什么?
gdb 是在 Linux 系统中的一款调试工具.
二、使用说明
1. 安装
首先先检测是否安装有 gdb:
bash
gdb -v
没有安装应该会提示: command not found. 此时输入指令进行安装:
bash
yum -y install gdb
而已经装有了, 则会显示类似信息:
2. 注意事项
在 Linux 下编译 C/C++ 代码时, 默认是 Release 版本的, 而 Release 版本是不携带调试信息的, 所以直接调试会失败:
因此在编译时要加上 -g 选项:
bash
g++ -o gdbTest gdbTest.cpp -g
此时就可以正常调试了:
3. 常用调试指令
用于当作例子使用 gdb 调试的代码, 其功能就是根据给定的 n, 从 1 累加到 n:
cpp
#include <iostream>
using namespace std;
int func(int n)
{
cout << "enter func" << endl;
int sum = 0;
for (int i = 1; i <= n; ++i)
{
sum += i;
}
cout << "quit func" << endl;
return sum;
}
int main()
{
int n = 100;
int res = func(n);
cout << "res: " << res << endl;
return 0;
}
3.1 gdb
gdb + 可执行文件名 : 进入调试界面
3.2 l
l + 行号 : 以那一行为开头显示 10 行的代码, 往后可以直接按回车, 则接着上次的位置往后显示代码, 一次显示10 行.
l + 函数名 : 以函数名所在的那一行为中心显示 10 行的代码, 往后可以直接按回车, 则接着上次的位置往后显示代码, 一次显示10 行.
3.3 r
在调试的状态下, 直接运行完整个程序, 类似于 vs 中的 ctrl + F5, 打了断点之后, 按 r 会直接运行到断点位置.
3.4 n
单条执行, 相当于 vs 中的 F10, 遇到函数不会进入其内部, 需要配合打断点使用, 先通过 r 运行到断电处, 此时再输入 n 即可实现单步调试.
3.5 s
相当于 vs 中的 F10, 遇到函数会进入其内部, 需要配合打断点使用, 先通过 r 运行到断电处, 此时再输入 s 即可实现调试.
3.6 b
b + 行号 : 给该行打上断点.
b + 函数名 : 给某个函数名的第一行执行语句打上断点.
虽然函数名在第 4 行, 但是该函数会执行的第一句语句在第 6 行, 所以断点打在了第 6 行.
3.7 info b
查看本次调试中打过的所有断点.
3.8 finish
进入函数后, 执行完整个函数, 并返回.
3.9 p
打印变量的值.
但它不是一直显示的, 在执行其他语句时会把它冲掉.
3.10 set var
设置变量的值, 可用于在循环中跳转到某一值.
3.11 c
从当前语句开始连续执行到离其最近的断点处, 可在循环外打上断点, 让其直接执行完循环, 直接获得循环结果.
3.12 d breakpoints
删除所有断点, 直接输入 d 也会达到同样的效果
在删除时会提示 Delete all breakpoints? (y or n), 选择 yes(y) 即可.
3.13 d n
删除断点 n, n 为断点的 Num, 每次调试的断点 Num 都是连续的, 在演示 delete breakpoints 时, 打了两个断点在 18, 19 行, 而它们的 Num 按顺序就是 1, 2, 当将它们都删除后, 再次打断点时, 断点的 Num 不会因为目前没有任何断点而重新从 1 开始编号, 而是会接着往下编号, 当退出此次调试, 重新开始另一次调试时, Num 会刷新, 从 1 开始编号.
3.14 disable/enable breakpoints
停用/启用所有断点.
Enb 表示断点的使能状态, y(yes) 表示启用, n(no) 表示停用, 默认都是 y, 关于断点的停用就相当于它不起作用, 即当它不存在, 通过其他指令也跳不到它.
停用所有断点:
启用所有断点:
3.15 disable/enable n
停用/启用断点 n.
3.16 info b
查看目前所打的所有断点的信息.
3.17 display 变量名/undisplay 编号
display 变量名 : 常显示变量的值, 弥补了 p 变量名只显示一次的缺陷, 每次执行新的语句, 都会显示跟踪显示变量的值.
undisplay 编号 : 取消变量的跟踪常显示, 需要注意的是, 和 display 不同, 取消变量的跟踪不是输入其变量名, 而是输入其 display 后获得的编号.
3.18 until n
执行完当前行和 n 行之间的内容, 跳到 n 行.
3.19 bt
查看函数调用栈.
3.20 ctrl + d/quit
退出调试.
输入 y 退出.