coredump
linux/Ubuntu下生成core dump文件调试方法
开启core dump
dbtu@dbtu:~$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 384811
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 384811
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
core file size
这一项为0,说明不生成core dump文件。
# 限制产生的 core 文件的大小不能超过 1024kb
$ ulimit -c 1024
# 取消转储文件大小限制
$ ulimit -c unlimited
但是,这样设置会有一个问题,就是这个命令只在当前打开的shell中生效,关闭后就失效了。想要每次打开shell都会生效,需要将命令写入~/.bashrc
或者/etc/profile
:
$ echo 'ulimit -c unlimited' >> ~/.bashrc
$ echo "ulimit -c 1024" >> /etc/profile
core dump文件保存的路径
/proc/sys/kernel/core_uses_pid
可以控制产生的 core 文件的文件名中是否添加 pid 作为扩展 ,如果添加则文件内容为 1 ,否则为 0 。
proc/sys/kernel/core_pattern
可以设置格式化的 core 文件保存位置或文件名,比如原来文件内容是 core-%e
,可以修改为 /tmp/corefile-%e-%p-%t
,即文件名格式“corefile-文件名-pid-时间戳”,保存到/tmp/
文件夹中。也可以不写文件夹,则直接保存到崩溃程序的同文件夹中。
还可以使用sysctl
命令来设置保存路径:
$ sudo sysctl -w kernel.core_pattern=core.%p.%s.%c.%d.%P.%E
每个%开头的符号含义请参考命令man 5 core
: core(5) — Linux manual page
Naming of core dump files
By default, a core dump file is named core, but the /proc/sys/kernel/core_pattern file (since Linux
2.6 and 2.4.21) can be set to define a template that is used to name core dump files. The template
can contain % specifiers which are substituted by the following values when a core file is created:
%% a single % character
%c core file size soft resource limit of crashing process (since Linux 2.6.24)
%d dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE (since Linux 3.7)
%e executable filename (without path prefix)
%E pathname of executable, with slashes ('/') replaced by exclamation marks ('!') (since Linux
3.0).
%g (numeric) real GID of dumped process
%h hostname (same as nodename returned by uname(2))
%i TID of thread that triggered core dump, as seen in the PID namespace in which the thread
resides (since Linux 3.18)
%I TID of thread that triggered core dump, as seen in the initial PID namespace (since Linux
3.18)
%p PID of dumped process, as seen in the PID namespace in which the process resides
%P PID of dumped process, as seen in the initial PID namespace (since Linux 3.12)
%s number of signal causing dump
%t time of dump, expressed as seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC)
%u (numeric) real UID of dumped process
A single % at the end of the template is dropped from the core filename, as is the combination of a %
followed by any character other than those listed above. All other characters in the template become
a literal part of the core filename. The template may include '/' characters, which are interpreted
as delimiters for directory names. The maximum size of the resulting core filename is 128 bytes (64
bytes in kernels before 2.6.19). The default value in this file is "core". For backward compatibil‐
ity, if /proc/sys/kernel/core_pattern does not include %p and /proc/sys/kernel/core_uses_pid (see
below) is nonzero, then .PID will be appended to the core filename.
Paths are interpreted according to the settings that are active for the crashing process. That means
the crashing process's mount namespace (see mount_namespaces(7)), its current working directory (found
via getcwd(2)), and its root directory (see chroot(2)).
Since version 2.4, Linux has also provided a more primitive method of controlling the name of the core
dump file. If the /proc/sys/kernel/core_uses_pid file contains the value 0, then a core dump file is
simply named core. If this file contains a nonzero value, then the core dump file includes the
process ID in a name of the form core.PID.
Since Linux 3.6, if /proc/sys/fs/suid_dumpable is set to 2 ("suidsafe"), the pattern must be either an
absolute pathname (starting with a leading '/' character) or a pipe, as defined below.
测试程序
#include <iostream>
int main() {
int *p = nullptr;
*p = 0;
return 0;
}
# 使用 -g 参数编译添加调试信息
$ g++ -g test.cpp -o testcore
# 运行调试程序
$ ./testcore
Segmentation fault (core dumped)
# 使用ls等命令找到coredump转储的文件,然后用gdb打开
$ gdb ./testcore core.testcore.1663553436.2705214
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./testcore...
warning: exec file is newer than core file.
[New LWP 2705214]
Core was generated by `./testcore'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00005562d441b17d in main () at test.cpp:5
5 *p = 0;
(gdb) where
#0 0x00005562d441b17d in main () at test.cpp:5
(gdb) info frame
Stack level 0, frame at 0x7ffd6863cc60:
rip = 0x5562d441b17d in main (test.cpp:5); saved rip = 0x7f0da5bb4083
source language c++.
Arglist at 0x7ffd6863cc48, args:
Locals at 0x7ffd6863cc48, Previous frame's sp is 0x7ffd6863cc60
Saved registers:
rbp at 0x7ffd6863cc50, rip at 0x7ffd6863cc58
(gdb)
从上面可以看出,我们可以还原 core_demo 执行时的场景,并使用 where
可以查看当前程序调用函数栈帧, 还可以使用 gdb
中的命令查看寄存器,变量等信息.