以ubuntu系统为例
lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal默认大小为0,表示不生成coredump文件,,如下所示
#ulimit -a 查看
core file size (blocks, -c) 0 (-c表示对应的选项)
data seg size (kbytes, -d) unlimited
#ulimit -c 或用这个命令
0(1)shell命令行临时设置,只在当前shell有效,其他shell无效,也可将配置放到启动脚本/etc/profile 或~/.bashrc等
#ulimit -c unlimited 设置
#ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
#ulimit -c
unlimited(2)配置永久有效:/etc/security/limits.conf
增加如下两行
* soft core unlimited
* hard core unlimited补充说明:
在 Linux 系统中,soft 和 hard 限制是指系统资源的两种类型的限制,用于控制用户对这些资源的使用。这两种限制通常在 /etc/security/limits.conf 文件中设置,以便控制用户进程可以消耗的资源量。这里是它们的具体意义:
以 ulimit 命令和 core 文件大小限制为例:
ulimit -S -c 查看当前 shell 的软限制(soft limit)。ulimit -H -c 查看当前 shell 的硬限制(hard limit)。ulimit -S -c unlimited 设置当前 shell 的软限制为无限。ulimit -H -c unlimited 设置当前 shell 的硬限制为无限(通常需要 root 权限)。通常情况下,软限制可以由用户自己在其软限制和硬限制之间调节,硬限制则需要管理员权限来进行修改。这种区分允许为用户提供一定的灵活性,同时仍然限制资源的最大使用量,以防止个别进程消耗过多资源导致系统不稳定。
ulimit -c unlimited这条命令设置的是核心转储(core dump)的大小限制。在没有指定使用-H(硬限制)或-S(软限制)参数的情况下,ulimit命令通常会设置软限制。
ubuntu 20.04里core dump默认由apport程序管理;已经配置到系统,不需要自己做任何额外设置,如下所示。默认apport对于软件包中的程序不生成coredump文件,而是上报,而对于开发自己的程序会生成coredump文件到/var/lib/apport/coredump目录,见后面的例子。
~$ 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
~$ sysctl kernel.core_pattern 或者用这个命令
kernel.core_pattern = |/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E配置解读:
在Ubuntu系统中,apport是一个错误报告系统,通常用来拦截程序崩溃时的core dumps,生成错误报告,并可能将它们提交到Ubuntu的错误跟踪系统中。该系统通常用于Ubuntu发行版,以便更好地收集和分析程序崩溃的信息。
/proc/sys/kernel/core_pattern中的配置:
|/usr/share/apport/apport %p %s %c %d %P %u %g -- %E指的是当程序崩溃产生core dump时,核心转储不直接写入磁盘成为文件,而是通过管道发送给apport程序进行处理。%p、%s、%c、%d、%P、%u、%g和%E这些是占位符,会被core dump的相关信息替换:
%p - 崩溃的进程的PID(进程ID)。%s - 导致进程终止的信号编号。%c - core dump的大小限制。%d - core dump的时间延迟(当core dump被触发时的延迟)。%P - 父进程的PID。%u - 进程的用户ID。%g - 进程的组ID。%E - 可执行文件的路径。Apport接收到这些信息后,会创建一个包含更多详细信息的报告(通常在/var/crash目录下),这也包括可能的调用栈、系统状态、应用程序版本等。报告包含足够的信息,以供开发者分析和解决问题,但通常不包含完整的core dump文件。
默认情况下,Apport在开发版发行版(如Ubuntu的Alpha/Beta版本)中是激活的,在正式发行版(如Ubuntu LTS)中默认是不激活的。用户可以选择将生成的错误报告提交给Ubuntu的开发者,以便修复报告中的错误。
如果你不想通过Apport处理core dumps,而是希望直接生成core dump文件,你可以通过修改/proc/sys/kernel/core_pattern来实现,在这个文件中指定一个文件路径模式,而不是调用Apport。这样设置后,发生崩溃时,core dumps将被直接保存为文件,供进一步分析。
如果想要直接获取core文件而非通过apport,你可以编辑/proc/sys/kernel/core_pattern文件并设置一个文件路径模式(例如 /tmp/core.%e.%p.%t),这样core dump就会直接被写入磁盘文件。
要修改core_pattern,你可以执行类似下面的命令:
echo '/tmp/core.%e.%p.%t' | sudo tee /proc/sys/kernel/core_pattern
sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t 或用这条命令这样,接下来产生的core dump文件就会被直接保存到/tmp目录下,文件名包含了程序名(%e)、进程ID(%p)和时间戳(%t)。
kernel.core_pattern 是一个内核参数,或者叫 “sysctl 设置”,它控制 Linux 内核将核心转储文件写到磁盘的哪里。内核参数是一种设定您的系统全局设置的方法。您可以通过运行 sysctl -a 得到一个包含每个内核参数的列表,或使用 sysctl kernel.core_pattern 来专门查看 kernel.core_pattern 设置。
停用apport,按需重启。
sudo systemctl disable apport.service这边采用默认的apport配置
下面是一个简单的C语言程序,它会故意制造一个段错误(segmentation fault),导致程序崩溃并生成core dump。这个程序包括一个递归函数调用,以便你在分析core dump时有一个调用堆栈可以查看。
#include <stdio.h>
void recursive_function(int counter) {
char *ptr = NULL;
// Print the counter and call itself to build up the stack
printf("Counter: %d\n", counter);
if (counter < 5) {
recursive_function(counter + 1);
} else {
// Deliberately cause a segmentation fault
*ptr = 'a';
}
}
int main() {
// Start the recursive function
recursive_function(0);
return 0;
}
复制要编译和运行这个程序,请按照下面的步骤操作:
coredump_example.cgcc -g -o coredump_example coredump_example.c
-g选项用于在编译时生成调试信息,这对于分析core dump是必要的。ulimit -c unlimited
这会移除core dump文件大小的限制。./coredump_example
该程序应该会打印出一些计数器的值然后崩溃。:~$ cat /var/log/apport.log
ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: called for pid 24553, signal 11, core limit 18446744073709551615, dump mode 1
ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: ignoring implausibly big core limit, treating as unlimited
ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: executable: /home/jay/codes/test/coredump/coredump_example (command line "./coredump_example")
ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: executable does not belong to a package, ignoring
ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: writing core dump to core._home_jay_codes_test_coredump_coredump_example.1000.4cae494e-6122-481e-be05-a1757e255a34.24553.76009719 (limit: -1)日志解读:
这些日志来自/var/log/apport.log,它记录了Ubuntu系统中Apport崩溃处理程序的活动。Apport是Ubuntu用来收集程序崩溃时的错误报告的工具。让我们逐条解释这些日志消息:
(1)ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: called for pid 24553, signal 11, core limit 18446744073709551615, dump mode 1
这条消息说的是,Apport(进程ID为24554)被调用来处理一个程序崩溃。程序的进程ID是24553,它因为信号11(即段错误,通常是因为非法内存访问)而崩溃。
core limit指的是系统为core dump文件设置的大小限制。18446744073709551615(或0xFFFFFFFFFFFFFFFF)是一个特别大的数字,通常表示无限制。
dump mode 1可能是内部指示,说明了Apport应该采取的处理方式。
(2)ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: ignoring implausibly big core limit, treating as unlimited
Apport注意到core limit非常大,它认为这个数字不太可能是合理的限制,所以将其当作无限制处理。
(3)ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: executable: /home/jay/codes/test/coredump/coredump_example (command line "./coredump_example")
这条消息指出了崩溃的可执行文件的路径,即/home/jay/codes/test/coredump/coredump_example,以及它的命令行调用方式。
(4)ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: executable does not belong to a package, ignoring
Apport发现崩溃的程序不是一个安装的软件包的一部分,因此它决定忽略这次崩溃。通常这意味着程序是用户自己编译的,不是通过系统软件包管理器安装的。
(5)ERROR: apport (pid 24554) Wed Jan 8 10:34:09 2025: writing core dump to core._home_jay_codes_test_coredump_coredump_example.1000.4cae494e-6122-481e-be05-a1757e255a34.24553.76009719 (limit: -1)
这条消息说明Apport正在将core dump写入一个文件,文件名包含了程序路径、用户ID(1000)、一个唯一标识符以及崩溃的进程ID和时间戳。这个文件名表明系统正在为崩溃的程序创建一个core dump文件,以便于进一步的问题分析。
(limit: -1)表明在写入core dump时,没有设置大小的限制。
这些日志条目显示了Apport如何响应一个程序崩溃,它提供了一些关键的信息,包括崩溃的进程ID、发生崩溃的原因、受影响的可执行文件,以及Apport如何处理这个崩溃。
:~$ ls -l /var/lib/apport/coredump
-r-------- 1 jay root 389120 1月 8 10:34 core._home_jay_codes_test_coredump_coredump_example.1000.4cae494e-6122-481e-be05-a1757e255a34.24553.76009719格式
gdb <executable> <coredump>然后就可以bt等各种gdb调试命令查看了,如下所示
$ gdb ./coredump_example /var/lib/apport/coredump/core._home_jay_codes_test_coredump_coredump_example.1000.4cae494e-6122-481e-be05-a1757e255a34.24553.76009719
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./coredump_example...
warning: core file may not match specified executable file.
[New LWP 24553]
Core was generated by `./coredump_example'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055bb3896918f in recursive_function (counter=5) at coredump_example.c:12
12 *ptr = 'a';
(gdb) bt
#0 0x000055bb3896918f in recursive_function (counter=5) at coredump_example.c:12
#1 0x000055bb38969189 in recursive_function (counter=4) at coredump_example.c:9
#2 0x000055bb38969189 in recursive_function (counter=3) at coredump_example.c:9
#3 0x000055bb38969189 in recursive_function (counter=2) at coredump_example.c:9
#4 0x000055bb38969189 in recursive_function (counter=1) at coredump_example.c:9
#5 0x000055bb38969189 in recursive_function (counter=0) at coredump_example.c:9
#6 0x000055bb389691a7 in main () at coredump_example.c:18
(gdb) info threads
Id Target Id Frame
* 1 LWP 24553 0x000055bb3896918f in recursive_function (counter=5) at coredump_example.c:12
(gdb) list
7 printf("Counter: %d\n", counter);
8 if (counter < 5) {
9 recursive_function(counter + 1);
10 } else {
11 // Deliberately cause a segmentation fault
12 *ptr = 'a';
13 }
14 }
15
16 int main() {
注意: 为了分析core dump,你的可执行文件应该包含调试信息。如果你没有带调试信息编译程序,堆栈信息可能不完整或缺少关键信息。在gcc中,你可以通过添加-g选项来编译你的程序以包含调试信息。
如果你想要Apport报告崩溃的话,你可能需要为你的本地程序创建一个包,或者调整Apport设置,以使其不忽略非包程序的崩溃。但这通常对于开发者和测试者来说不是必须要做的。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。