存档

文章标签 ‘coredump’

Linux Coredump 核心转储

2019/10/14 7,249

什么是 Coredump

coredump 核心转储 ,也称为 核心文件(core file) 是操作系统在进程收到某些 信号 而终止运行时,将此进程的地址空间以内容以及有关进程状态的其他信息写出的一个文件。这种信息往往用于调试。
程序员可以通过工具来分析程序运行过程中哪里出错了:Windows 平台用 userdump 和 WinDBG ,Linux 平台使用gdb, elfdump, objdump 等

Windows WinDBG

关于 windbg, 可以参考以下资料

Linux GDB

有些时候进程在crash的时候会产生 core 文件, 但我们却找不到 core 文件,我们需要使用 ulimit 进行一些设置, 这个命令是用来限制系统用户对shell资源的访问的。
ulimit -a 可以查看当前的设置
ulimit -c 可以设置 core 文件的上限,单位为区块(一般 1 block = 512 bytes) .其值为 0 时不写入 core, 为 unlimited 时不限制 core 文件大小。
需要注意, ulimit 只对当前会话有效。若想对所有会话生效, 需要在 /etc/profile 中进行配置。

源文件如下 test_vec.cpp :

#include <iostream>
#include <vector>
using namespace std;

int main(){
        std::vector<int> v{42};
        cout<<v.at(5)<<endl;  //Will crash, and coredump
        return 0;
}

编译运行时可能出现如下现象:

$ g++ -o t_vec ./test_vec.cpp
$ ./t_vec
terminate called after throwing an instance of 'std::out_of_range'
  what(): vector::_M_range_check: __n (which is 5) >= this->size() (which is 1)
Aborted (core dumped)

使用 gdb 打开来看:

$ gdb t_vec core
Core was generated by `./t_vec'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) i s
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007fbe77c7f801 in __GI_abort () at abort.c:79
#2 0x00007fbe782d4957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007fbe782daab6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007fbe782daaf1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007fbe782dad24 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007fbe782d6855 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x000055a4f8cda08a in std::vector<int, std::allocator<int> >::_M_range_check(unsigned long) const ()
#8 0x000055a4f8cd9e9d in std::vector<int, std::allocator<int> >::at(unsigned long) ()
#9 0x000055a4f8cd9c11 in main ()
(gdb)

从 gdb显示的栈信息来看,崩溃发生在 main 函数内的 vector::at 函数内,由 _M_range_check raise 。
如果我们在编译时使用了 -g 选项, 会得到更详细的信息

继续阅读