这篇文章我们来学习 gdb 的使用方法。我们在Windows端编写代码时有宇宙最强编译器VS2022帮助我们调试,那Linux端有没有一款强大的调试工具呢???
当然有了 它就是 gdb :
Linux下的gdb(GNU Debugger)是一款强大的调试工具,对于程序员来说,掌握gdb的使用技巧是开发过程中必不可少的技能。根据Statista的数据,截至2023,Linux在全球服务器操作系统市场占据近37%的份额,这使得gdb成为了许多专业人士必备的工具。。
本文将介绍如何使用gdb。
1 下载安装
首先我们要确保已经安装gdb,可以通过 gdb -version
来进行间接查看。
未安装使用sudo yum -y install gdb
下载安装即可。
2 开始使用
首先进入gdb直接使用:gdb 文件名
接下来我直接给出 gdb 的 所有功能命令(注意简写形式,会经常使用):
- list /l 行号:显示指定行号附近的源代码,每次显示10行,从当前光标位置向下滚动。
- list /l 函数名:显示指定函数的完整源代码。
- r 或 run:开始执行程序。
- n 或 next:执行下一条语句,不会进入函数内部。相当于 F10
- s 或 step:执行下一条语句,如果下一条语句是函数调用,则进入该函数内部。 相当于 F11
- break(b) 行号:在指定的行号设置断点。相当于 F9
- break 函数名:在指定函数的开头设置断点。
- info break:显示所有断点的信息。
- finish:执行当前函数的剩余部分,直到函数返回,然后暂停程序。
- print ( p ) 表达式:计算并打印表达式的值。
- p 变量:打印变量的值。
- set var:修改变量的值。
- continue(或c):继续执行程序,直到下一个断点或程序结束。相当于 F5
- run(或r):从程序的开始处执行程序,直到程序结束或遇到断点。
断点相关操作:
- delete breakpoints:删除所有断点。
- delete breakpoints n:删除指定编号的断点。
- disable breakpoints:禁用所有断点。
- enable breakpoints:启用所有断点。
- ignore:忽略特定的断点。例如,ignore 1 main 会让断点1在主函数上失效
- info(或i) breakpoints:显示当前设置的所有断点。
- 监视相关操作:
- display 变量名:跟踪指定变量的值,并在每次程序暂停时显示它。
- undisplay:取消对先前设置的变量的跟踪。
- until X行号:继续执行程序,直到达到指定的行号。
- breaktrace(或bt):显示程序的调用栈,包括所有函数的调用和参数。
- info(i) locals:显示当前函数栈帧中局部变量的值。
- quit:退出GDB。
3 实践运用
接下来我们在实践中加深对gdb的熟悉:
首先我们编写一段简单程序:
1 #include<iostream> 2 using namespace std; 3 4 int main(){ 5 int i = 0; 6 int j = 100; 7 8 while(i < 100){ 9 int sum = i + j; 10 i++; 11 j -= 2; 12 } 13 14 for(int k = 0;k<10;k++){ 15 cout<<"hello bit"<<endl; 16 } 17 18 19 return 0; 20 }
然后我们直接进入gdb
出乎意料的是 再使用list出现了报错(No symbol table is loaded. Use the “file” command.)!!!
这是因为 gdb操作的应该是编译后的文件
当编译时,未加 - g 选项,则进入gdb环境中执行命令会出现No symbol table is loaded. Use the “file” command.提示;
一定要进行gcc/g++ -g test.c -o test
操作哦。
这样就好了:成功显示出我们代码
接下来我们打开监视,来看看每个变量的变化。我们先打上断点来进入主函数:
然后逐个 display 展示即可:
然后调试(continue、step、next)就好,可以清楚看到每个变量的值
我们来试试断点的快速移动:
我们直接就跳出了正在进行的while循环,来到14行了。
其他指令就不进行探索了,熟悉使用就可以了。
补充一下 print 的 功能 (类似监视窗口的作用)和显示堆栈的功能
- 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() 函数
- watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a
- whatis :查询变量或函数
- info function: 查询函数,扩展info locals: 显示当前堆栈页的所有变量
堆栈:
- where/bt :当前运行的堆栈列表;
- bt backtrace 显示当前调用堆栈
- up/down 改变堆栈显示的深度
- set args 参数:指定运行时的参数
- show args:查看设置好的参数
- info program: 来查看程序的是否在运行,进程号,被暂停的原因。