一、 简介

当踩内存,发生段错误(segment falut/signal 11)时,常使用bt/backtrace命令,查看程序调用栈,定位踩内存位置。

当程序崩溃时(不限于段错误,例如可用kill发送指定信号到进程引发“崩溃”),会发生“吐核”(core dump),将内存“快照/镜像“信息转存到磁盘中,可以利用core文件调试。在Linux系统下“吐核”需要使用命令ulimit手动开启(默认时不产生core文件)。

二、说明

(gdb) backtrace
(gdb) bt - 查看调用栈信息
输出说明:
#[帧号] 函数地址 in 函数名(参数...) at 源文件名:调用行数
(gdb) bt full - 查看调用栈信息及所有局部变量/参数值
(gdb) bt [层数] - 查看调用栈信息/仅输出给定层数

(gdb) up - 上一帧,调用现在帧位置
(gdb) down - 下一帧,现在帧调用位置
(gdb) frame [帧号] - 切换到指定帧
(gdb) info frame - 显示当前帧寄存器等详细数据

(gdb) info locals - 显示当前帧所有局部变量值
(gdb) print [变量名] - 输出变量值

(gdb) list - 显示附近源代码

三、示例

开启Linux产生core文件(注:不限制文件大小)。

$ ulimit -c unlimited

运行踩内存程序生成core文件,文件名默认为core.[pid]

// file : test.cpp
struct node {
    int value_;
    node* next_;
    node(int v) { value_ = v;next_ = nullptr;}
};

void call_func(node* root) {
    int i = root->value_;// nullptr
    node* next = root->next_; 
    call_func(next);
}

int main() {
    node* root = new node(1);
    root->next_ = new node(2);
    root->next_->next_ = new node(3);
    call_func(root);
}
$ g++ -o t test.cpp -g
$ ./t
段错误(吐核)

调试core文件,定位到访问空内存位置。

# 使用命令: gdb [程序] [core文件]
$ gdb ./t core.file
(gdb) bt
#0  0x00000000004006e2 in call_func (root=0x0) at test.cpp:13
#1  0x00000000004006ff in call_func (root=0x852c60) at test.cpp:15
#2  0x00000000004006ff in call_func (root=0x852c40) at test.cpp:15
#3  0x00000000004006ff in call_func (root=0x852c20) at test.cpp:15
#4  0x000000000040077d in main () at test.cpp:22
(gdb) frame 1
#1  0x00000000004006ff in call_func (root=0x852c60) at test.cpp:15
15          call_func(root);
(gdb) info locals
i = 3
next = 0x0

四、参考

Last modification:May 12th, 2020 at 07:46 pm