GDB调试方式一般有三种:
启动调试前确保该程序生成调试信息
gdb相关调试命令:
命令 | 缩写 | 描述 |
run | r | 运行一个程序 |
continue | c | 让暂停的程序继续运行 |
break | b | 添加断点 |
tbreadk | tb | 添加临时断点 |
backtrace | bt | 查看当前线程的调用堆栈 |
frame | f | 切换到当前调用线程的指定堆栈 |
info | info | 查看断点,线程等信息 |
enable | enable | 启用某个断点 |
disable | disable | 禁用某个断点 |
delete | del | 删除断点 |
list | l | 显示源码 |
p | 打印或修改变量、寄存器的值 | |
ptype | ptype | 查看变量类型 |
thread | thread | 切换到指定线程 |
next | n | 运行到下一行 |
step | s | 如果有调用函数,进入函数内部 |
until | u | 运行到指定的行停下来 |
finish | fi | 结束当前调用函数,到上一层函数调用处 |
return | return | 结束当前调用并返回指定的值,到上一层调用处 |
jump | j | 将当前程序的执行流跳转到指定的行或地址 |
disassemble | dis | 查看汇编代码 |
watch | watch | 监视某一变量 |
display | display | 监视某一变量,程序结束输出 |
dir | dir | 重定向源码文件的位置 |
编译生成时:
g++/gcc -g -o test test.cpp //-g为生成调试信息
一、gdb 直接启动程序调试
gdb testname //testname为程序名称
然后使用相关命令查看程序内存信息;
二、gdb 附加进程调试
gdb attach pID //pID程序运行pid
然后使用命令查看程序内存信息
退出attach
distach //解除绑定attach,不影响程序继续运行
三、gdb调试程序崩溃 (调试core文件,定位程序崩溃问题)
Demo程序段:
#include <iostream>
using namespace std;
class A
{
public:
A(){m_a = 10;};
int Get()
{
return m_a;
};
int m_a;
};
int main()
{
A* a = 0;
cout<<"A调用"<<a->Get()<<endl; //非正常程序,测试
int B[10] = {0};
for(int i = 0 ; i < 15;i++)
{
int c = B[i]; //非正常程序,测试
cout<<"c="<<c<<endl;
}
cout<<"hello world";
return 0;
}
确保设置生成core文件
ulimit -c
如果输出size为0,表示没有开启生成core文件
开启:
ulimit -c unlimited //unlimited 表示生成不限制大小的core文件,也可以指定大小
开启后可以通过命令查看是否配置成功
表示配置成功
这样的方式配置只是临时的,如果需要永久生效,需要修改/etc/security/limits.conf文件
#<domain> <type> <item> <value>
* soft core unlimited
把ulimit -c unlimited 行添加到/etc/profile文件中, 生效配置
source /etc/profile
开始测试demo程序,运行后
程序崩溃,并在当前目录下生成core.3730的文件,调试这个文件即可定位程序错误
gdb test core.3730
输出信息显示,在程序11行调用时有空指针;
最后可以根据提示修改代码,解决崩溃;