core dump 介绍
在 Linux 环境下调试 C/C++ 程序时,经常会因为内存访问错误产生段错误(核心已转储),而在当前目录却找不到转储的 core 文件,此时需要检查系统 core dump 配置是否打开。
如果打开系统 core dump 功能,那么在程序运行报段错误后,系统就会将程序的内存映像转储到硬盘,随后可以用 gdb 对生成的 core 文件进行分析,还原程序发生段错误时刻的堆栈调用信息。
查看系统 core dump 配置
通过 ulimit -a
命令查看系统 core 文件的大小限制,可以看到第一行 core file size 设置为 0,即没有打开 core dump 开关。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| lhx@ubuntu:~$ 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) 31400 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) 31400 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
|
设置系统生成的 core 文件大小
使用 ulimit -c [kbytes]
命令设置系统允许生成的 core 文件大小。
- ulimit -c 0 :不产生 core 文件
- ulimit -c 100 :设置 core 文件最大为 100kb
- ulimit -c unlimited :不限制 core 文件大小
通常会设置为 unlimited,即不限制文件大小。
1
| lhx@ubuntu:~$ ulimit -c unlimited
|
然后,再查看下系统 core dump 配置,可以看到第一行 core file size 变为了 unlimited。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| lhx@ubuntu:~$ ulimit -a core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 31400 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) 31400 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
|
配置 core 文件保存路径
core 文件具体存放在哪个目录取决于系统参数 kernel.core_pattern:
1 2
| root@ubuntu:# cat /proc/sys/kernel/core_pattern |/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E
|
修改 /proc/sys/kernel/core_pattern
设置格式化的 core 文件保存位置或文件名:
1 2 3 4 5 6 7
| root@ubuntu:# cat /proc/sys/kernel/core_pattern |/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E
root@ubuntu:# echo "/home/lhx/test/coredump/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
root@ubuntu:/home/lhx/test/coredump# cat /proc/sys/kernel/core_pattern /home/lhx/test/coredump/core-%e-%p-%t
|
% E:添加可执行程序的完整路径
% e:添加可执行程序名
% p:添加 pid
% t:进程奔溃的时间戳
% s:添加导致产生 core 的信号
% u - 添加当前 uid
% g - 添加当前 gid
然后重新设置 ulimit,再测试一下,发现生成了对应的 core 文件:
1 2 3 4 5
| root@ubuntu:/home/lhx/test/coredump# ulimit -c unlimited root@ubuntu:/home/lhx/test/coredump# ./a.out 段错误 (核心已转储) root@ubuntu:/home/lhx/test/coredump# ls a.out core-a.out-9209-1653703102 coredump.c
|
复杂情况处理
一般情况下,使用 ulimit -c unlimited
命令后,会默认在当前目录生成对应 core 文件。
如果当前目录没有找到 core 文件,使用命令 cat /proc/sys/kernel/core_pattern
却看到 /usr/share/apport/apport
类似的路径,注意这个并不是系统保存的路径!Ubuntu 下 coredump 会被 Apport 来处理。
此时建议进行格式化设置 core 文件路径和名称,然后,基本就能正常显示 core 文件。
如果还是找不到 core 文件,则使用下面的终极方法:
使用 cat /var/log/apport.log
查看日志:
1 2 3 4 5 6
| root@ubuntu:/usr/share/apport# cat /var/log/apport.log ERROR: apport (pid 3164) Fri May 27 22:29:20 2022: called for pid 3163, signal 11, core limit 18446744073709551615, dump mode 1 ERROR: apport (pid 3164) Fri May 27 22:29:20 2022: ignoring implausibly big core limit, treating as unlimited ERROR: apport (pid 3164) Fri May 27 22:29:20 2022: executable: /home/lhx/test/coredump/a.out (command line "./a.out") ERROR: apport (pid 3164) Fri May 27 22:29:20 2022: executable does not belong to a package, ignoring ERROR: apport (pid 3164) Fri May 27 22:29:20 2022: writing core dump to core._home_lhx_test_coredump_a_out.0.b0a0dac1-9489-4362-b93e-5b795f497130.3163.16880 (limit: -1)
|
会看到一行关键信息,包含可执行程序名称、路径和时间戳,这就是 core 文件:
1
| ERROR: apport (pid 3164) Fri May 27 22:29:20 2022: writing core dump to core._home_lhx_test_coredump_a_out.0.b0a0dac1-9489-4362-b93e-5b795f497130.3163.16880 (limit: -1)
|
然后全局范围内搜索文件名,会发现 core 文件位于 /var/lib/apport/coredump/
目录:
1 2
| lhx@ubuntu:/$ sudo find . -name "core._home_lhx_test_coredump_a_out.0.b0a0dac1*" /var/lib/apport/coredump/core._home_lhx_test_coredump_a_out.0.b0a0dac1-9489-4362-b93e-5b795f497130.3163.16880
|
其他注意事项
- 注意
ulimit -c unlimited
命令只针对当前 shell 窗口有效。
- 格式化设置 core 文件路径和名称时,注意要用 root 或 sudo 权限。
- 如果上述方法还是不行,建议全局使用 root 账户。