gdb调试
安装gdb
使用前需要安装gdb:
yum install -y gdb
使用前的准备
在编译文件时,需要加入参数-g 来确保编译后的文件可以被调试。
g++ -g demo.cpp -o demo
使用gdb
demo代码1
#include <unistd.h>
#include <bits/stdc++.h>
using namespace std;
void print()
{
cout << "hello world 111" << endl;
cout << "hello world 222" << endl;
cout << "hello world 333" << endl;
}
int main(int argc, char **argv)
{
for (int i = 0; i < argc; i++)
cout << i << ' ' << argv[i] << endl;
int a = 1;
cout << a << endl;
a++;
cout << a << endl;
a++;
cout << a << endl;
print();
a++;
cout << a << endl;
a++;
cout << a << endl;
return 0;
}
进入调试
gdb 可执行文件名
成功进入gdb调试后,可以发现命令行首部描述符变成了(gdb)格式。
运行程序
run命令开始运行程序,遇到断点会停止,如果没有断点则运行结束。该命令可简写成r
(gdb) r
由于未设置断点,可以发现程序运行结束。
设置断点
break 行号,在该行设置断点,运行到该行时程序会停止。该命令可简写成b
(gdb) break row_id
由于在12行设置了一个断点,执行run命令后,程序在12行停止。
下一步
有两个命令都是下一步。
next命令,执行当前语句,如果遇到函数调用,不会进入函数内部(执行了函数,但是gdb并没有进入函数内部)。该命令可简写成n
(gdb) next
step命令,执行当前语句,如果遇到函数调用(不可以是库函数,需要时自己声明的函数),会进入函数内部。该命令可简写成s
(gdb) step
继续执行
在遇到断点、程序停止之后,我们可以使用continue命令来继续执行程序直到遇到下一个断点。该命令可简写成c
(gdb) continue
在遇到断点之后,程序停止在了12行,输入continue命令,程序继续执行直到结束。
设置主函数参数
demo代码中,运行程序时可以像下面这样在主函数中传入参数。
./demo arg1 arg2 arg1000
下面是运行结果: 但是在gdb模式下,我们不能像这样传入参数了。
因此我们需要用新的方式给主程序传入参数:
(gdb) set args 参数1 参数2 ... ...
打印变量
使用print命令可以查看变量值。改名了可简写成p
(gdb) print a
退出
使用quit命令退出gdb调试。该命令可简写成q
(gdb) quit
coredump
Linux中,ulimit命令用来控制shell执行程序的资源。在使用coredump之前,我们需要将core文件最大值设置为unlimited
ulimit -c unlimited
程序在遇到异常终止后,会产生一个core文件,可以使用它对程序进行调试。
demo代码2
#include <unistd.h>
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char **argv)
{
cout << 1 / 0 << endl;
return 0;
}
编译运行以上代码,程序会发生错误并终止,使用ls命令查看文件,可以发现出现了一个core文件。
使用以下命令对core文件进行调试
gdb 可执行文件名 对应的core文件
比较直观的能看到出错的语句,当然其他信息也是很有用的。
程序日志
使用程序log的形式进行调试。本质上是输出中间结果的一种调试方式,相对于gdb调试的优点是调试期间不会暂停程序,更接近于实际环境。
参考资料
-
C语言技术网 -
Bilibili_C语言技术网_C语言gdb调试之精髓
|