Linux 下 启用 core dump,并进行分析 gaunthan Posted on Aug 17 2020 ? Linux ? ? Linux Tutorial ? > 在程序崩溃时,通常我们只能得到一个segfault之类的提示信息。如果想要定位崩溃原因,我们需要更详细的内容,如运行堆栈等。为此,可以启用core dump功能,程序崩溃时,操作系统会生成一个相应的core dump文件,可以随后使用gdb对它进行分析。 ## 查看和启用core dump ### 查看是否启用core dump 在Linux下,可以使用`ulimit -c`命令查看core dump的限制:  这个命令显示core dump文件的限制大小,显示为0,表示不生成。 ### 临时启用 可以在`ulimit -c`选项后传入大小参数,指定core dump文件的最大大小。如果不希望对此进行限制,可以传递`unlimited`,如`ulimit -c unlimited`。 此时再查看限制大小,会发现其已经更改为:  但是这种方式只对当前shell起作用,而且退出shell后就失效了。 ### 永久启用 想要整个系统永久启用,需要修改`/etc/security/limits.conf`文件,在末尾添加配置: ```txt * soft core unlimited ``` 如果配置成`soft`的方式,为了让配置生效,需要退出重登。配置成`hard`的方式则下一个创建的进程将直接使用该配置,此时直接启动程序即可。 ## 示例 ```cpp #include <iostream> #include <cassert> using namespace std; void foo() { assert(false); } int main() { cout << "before calling foo()" << endl; foo(); cout << "after calling foo()" << endl; return 0; } ``` 编译运行后会在执行目录生成一个core dump文件:  ## 分析core文件 使用`gdb program core`方式运行gdb:  然后可以使用`bt`命令打印调用堆栈:  如图所示,行号越小,调用越近发生。我们跳过库里面的调用,着眼于我们编写的调用,即`#4`行,提示在`example.cpp`文件的第8行,而这就是我们调用`assert`的地方:  ## core dump的相关配置 |文件|作用| |--|--| |/proc/sys/kernel/core_pattern|定义了core文件名的生成格式| |/proc/sys/kernel/core_uses_pid|如果这个文件的内容被配置成1,那么即使core_pattern中没有设置%p,最后生成的core dump文件名仍会加上进程ID| |/proc/sys/kernel/core_pipe_limit|定义了可以有多少个并发的崩溃程序可以通过管道模式传递给指定的core信息收集程序,如果超过,异常信息将被丢弃。0表示不限制并行捕捉的进程个数| 注意上面的配置都是临时的,想要永久生效的话,需要在`/etc/sysctl.conf`中加入相应配置,如: ```bash kernel.core_pattern = /var/core_log/core_%e_%t_%p kernel.core_uses_pid = 0 ``` 然后使用`sysctl –p`命令使配置立即生效。 ### core文件名的生成格式 默认情况下,core dump在崩溃程序的执行路径下生成。可以通过修改`/proc/sys/kernel/core_pattern`指定生成路径,该文件内容的默认内容为"core",可以如此定义指定其生成路径为/var/core_log/:`/var/corefile/core_%e_%t_%p`。 其中的`%e_%t_%p`分别代表程序名、转储时间以及进程ID。 PS:可以通过`ls -ld /proc/(pid)/cwd`获得进程pid的工作目录。在不知道corefile的生成路径时,可以用该方法找到进程的core文件。 ## 参考文献 - [linux下core dump【总结】](https://www.cnblogs.com/Anker/p/6079580.html) - [gdb调试coredump(使用篇)](https://zhuanlan.zhihu.com/p/46605905) 赏 Wechat Pay Alipay Windows 10, WSL2 显示 GUI 窗口 掌握这些常见的 Shell 命令,轻松驾驭 Linux