您现在的位置是:首页 > 编程 > 

coredump分析

2025-07-26 08:45:22
coredump分析 以ubuntu系统为例代码语言:txt复制 lsb_release -a o LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focalcoredump文件大小设置查看cored

coredump分析

以ubuntu系统为例

代码语言:txt复制
 lsb_release -a
o LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.6 LTS
Release:        20.04
Codename:       focal

coredump文件大小设置

查看coredump文件大小限制

默认大小为0,表示不生成coredump文件,,如下所示

代码语言:txt复制
#ulimit -a   查看
core file size          (blocks, -c) 0        (-c表示对应的选项)
data seg size           (kbytes, -d) unlimited
#ulimit -c   或用这个命令
0
设置coredump文件大小限制

(1)shell命令行临时设置,只在当前shell有效,其他shell无效,也可将配置放到启动脚本/etc/profile 或~/.bashrc等

代码语言:txt复制
#ulimit -c unlimited  设置
#ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
#ulimit -c
unlimited

(2)配置永久有效:/etc/security/

增加如下两行

代码语言:javascript代码运行次数:0运行复制
* soft core unlimited
* hard core unlimited

补充说明:

在 Linux 系统中,softhard 限制是指系统资源的两种类型的限制,用于控制用户对这些资源的使用。这两种限制通常在 /etc/security/ 文件中设置,以便控制用户进程可以消耗的资源量。这里是它们的具体意义:

  • Soft Limit(软限制):这是系统对资源使用的警告阈值。用户可以增加其软限制,但不能超过相应的硬限制值。用户的进程可以临时超出软限制,但是当超出时会收到系统的警告。
  • Hard Limit(硬限制):这是系统强制执行的资源使用上限。普通用户不能设置超过硬限制的值,只有具有 root 权限的用户才能增加硬限制。硬限制定义了用户或进程可用资源的最大值,用户和进程都不能超过这个限制。

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命令通常会设置软限制。

coredump文件格式设置

默认coredump文件传递给apport分析处理

ubuntu 20.04里core dump默认由apport程序管理;已经配置到系统,不需要自己做任何额外设置,如下所示。默认apport对于软件包中的程序不生成coredump文件,而是上报,而对于开发自己的程序会生成coredump文件到/var/lib/apport/coredump目录,见后面的例子。

代码语言:txt复制
~$ 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 _pattern  或者用这个命令
_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中的配置:

代码语言:javascript代码运行次数:0运行复制
|/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将被直接保存为文件,供进一步分析。

禁用apport并使系统生成传统的coredump文件

如果想要直接获取core文件而非通过apport,你可以编辑/proc/sys/kernel/core_pattern文件并设置一个文件路径模式(例如 /tmp/core.%e.%p.%t),这样core dump就会直接被写入磁盘文件。

要修改core_pattern,你可以执行类似下面的命令:

代码语言:javascript代码运行次数:0运行复制
echo '/tmp/core.%e.%p.%t' | sudo tee /proc/sys/kernel/core_pattern
sudo sysctl -w _pattern=/tmp/core-%e.%p.%h.%t  或用这条命令

这样,接下来产生的core dump文件就会被直接保存到/tmp目录下,文件名包含了程序名(%e)、进程ID(%p)和时间戳(%t)。

_pattern 是一个内核参数,或者叫 “sysctl 设置”,它控制 Linux 内核将核心转储文件写到磁盘的哪里。内核参数是一种设定您的系统全局设置的方法。您可以通过运行 sysctl -a 得到一个包含每个内核参数的列表,或使用 sysctl _pattern 来专门查看 _pattern 设置。

停用apport,按需重启。

代码语言:javascript代码运行次数:0运行复制
sudo systemctl disable apport.service

coredump案例调试分析

这边采用默认的apport配置

demo编写

下面是一个简单的C语言程序,它会故意制造一个段错误(segmentation fault),导致程序崩溃并生成core dump。这个程序包括一个递归函数调用,以便你在分析core dump时有一个调用堆栈可以查看。

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>

void recursive_function(int counter) {
    char *ptr = ULL;

    // 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;
}
复制

要编译和运行这个程序,请按照下面的步骤操作:

  1. 保存上面的代码到一个文件中,例如coredump_
  2. 在终端中,使用gcc编译器编译这个程序: gcc -g -o coredump_example coredump_ -g选项用于在编译时生成调试信息,这对于分析core dump是必要的。
  3. 确保系统允许生成core dump文件。你可以通过运行以下命令来检查或设置core dump文件的大小限制: ulimit -c unlimited 这会移除core dump文件大小的限制。
  4. 运行编译后的程序:./coredump_example 该程序应该会打印出一些计数器的值然后崩溃。
coredump日志/var/log/apport.log查看代码语言:txt复制
:~$ cat /var/log/apport.log
ERROR: apport (pid 24554) Wed Jan  8 10:4:09 2025: called for pid 2455, signal 11, core limit 1844674407709551615, dump mode 1
ERROR: apport (pid 24554) Wed Jan  8 10:4:09 2025: ignoring implausibly big core limit, treating as unlimited
ERROR: apport (pid 24554) Wed Jan  8 10:4:09 2025: executable: /home/jay/codes/test/coredump/coredump_example (command line "./coredump_example")
ERROR: apport (pid 24554) Wed Jan  8 10:4:09 2025: executable does not belong to a package, ignoring
ERROR: apport (pid 24554) Wed Jan  8 10:4:09 2025: writing core dump to core._home_jay_codes_test_coredump_coredump_example.1000.4cae494e-6122-481e-be05-a1757e255a4.2455.76009719 (limit: -1)

日志解读:

这些日志来自/var/log/apport.log,它记录了Ubuntu系统中Apport崩溃处理程序的活动。Apport是Ubuntu用来收集程序崩溃时的错误报告的工具。让我们逐条解释这些日志消息:

(1)ERROR: apport (pid 24554) Wed Jan 8 10:4:09 2025: called for pid 2455, signal 11, core limit 1844674407709551615, dump mode 1

这条消息说的是,Apport(进程ID为24554)被调用来处理一个程序崩溃。程序的进程ID是2455,它因为信号11(即段错误,通常是因为非法内存访问)而崩溃。

core limit指的是系统为core dump文件设置的大小限制。1844674407709551615(或0xFFFFFFFFFFFFFFFF)是一个特别大的数字,通常表示无限制。

dump mode 1可能是内部指示,说明了Apport应该采取的处理方式。

(2)ERROR: apport (pid 24554) Wed Jan 8 10:4:09 2025: ignoring implausibly big core limit, treating as unlimited

Apport注意到core limit非常大,它认为这个数字不太可能是合理的限制,所以将其当作无限制处理。

()ERROR: apport (pid 24554) Wed Jan 8 10:4: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:4:09 2025: executable does not belong to a package, ignoring

Apport发现崩溃的程序不是一个安装的软件包的一部分,因此它决定忽略这次崩溃。通常这意味着程序是用户自己编译的,不是通过系统软件包管理器安装的。

(5)ERROR: apport (pid 24554) Wed Jan 8 10:4:09 2025: writing core dump to core._home_jay_codes_test_coredump_coredump_example.1000.4cae494e-6122-481e-be05-a1757e255a4.2455.76009719 (limit: -1)

这条消息说明Apport正在将core dump写入一个文件,文件名包含了程序路径、用户ID(1000)、一个唯一标识符以及崩溃的进程ID和时间戳。这个文件名表明系统正在为崩溃的程序创建一个core dump文件,以便于进一步的问题分析。

(limit: -1)表明在写入core dump时,没有设置大小的限制。

这些日志条目显示了Apport如何响应一个程序崩溃,它提供了一些关键的信息,包括崩溃的进程ID、发生崩溃的原因、受影响的可执行文件,以及Apport如何处理这个崩溃。

coredump目录/var/lib/apport/coredump查看代码语言:txt复制
:~$ ls -l  /var/lib/apport/coredump
-r-------- 1 jay root 89120 1月   8 10:4 core._home_jay_codes_test_coredump_coredump_example.1000.4cae494e-6122-481e-be05-a1757e255a4.2455.76009719
gdb调试coredump文件

格式

代码语言:javascript代码运行次数:0运行复制
gdb <executable> <coredump>

然后就可以bt等各种gdb调试命令查看了,如下所示

代码语言:txt复制
$ gdb ./coredump_example /var/lib/apport/coredump/core._home_jay_codes_test_coredump_coredump_example.1000.4cae494e-6122-481e-be05-a1757e255a4.2455.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.
[ew LWP 2455]
Core was generated by `./coredump_example'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055bb896918f in recursive_function (counter=5) at coredump_:12
12              *ptr = 'a';
(gdb) bt
#0  0x000055bb896918f in recursive_function (counter=5) at coredump_:12
#1  0x000055bb8969189 in recursive_function (counter=4) at coredump_:9
#2  0x000055bb8969189 in recursive_function (counter=) at coredump_:9
#  0x000055bb8969189 in recursive_function (counter=2) at coredump_:9
#4  0x000055bb8969189 in recursive_function (counter=1) at coredump_:9
#5  0x000055bb8969189 in recursive_function (counter=0) at coredump_:9
#6  0x000055bb89691a7 in main () at coredump_:18
(gdb) info threads
  Id   Target Id         Frame
* 1    LWP 2455         0x000055bb896918f in recursive_function (counter=5) at coredump_: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';
1          }
14      }
15
16      int main() {

注意: 为了分析core dump,你的可执行文件应该包含调试信息。如果你没有带调试信息编译程序,堆栈信息可能不完整或缺少关键信息。在gcc中,你可以通过添加-g选项来编译你的程序以包含调试信息。

如果你想要Apport报告崩溃的话,你可能需要为你的本地程序创建一个包,或者调整Apport设置,以使其不忽略非包程序的崩溃。但这通常对于开发者和测试者来说不是必须要做的。

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1190358.html

相关标签:无
上传时间: 2025-07-22 20:20:17
留言与评论(共有 11 条评论)
本站网友 梦到丢鞋
2分钟前 发表
使用gcc编译器编译这个程序: gcc -g -o coredump_example coredump_ -g选项用于在编译时生成调试信息
本站网友 生姜的功效与作用
15分钟前 发表
程序的进程ID是2455
本站网友 跑步减肥的最佳时间
2分钟前 发表
%s - 导致进程终止的信号编号
本站网友 44519
15分钟前 发表
20.04 Codename
本站网友 青果炖猪肚
0秒前 发表
运行编译后的程序:./coredump_example 该程序应该会打印出一些计数器的值然后崩溃
本站网友 dabomei
12分钟前 发表
9 # 0x000055bb8969189 in recursive_function (counter=2) at coredump_
本站网友 第一产业增加值
11分钟前 发表
~$ cat /var/log/apport.log ERROR
本站网友 全面发展
6分钟前 发表
确保系统允许生成core dump文件
本站网友 缬沙坦召回
13分钟前 发表
例如coredump_在终端中
本站网友 欧派橱柜怎么样
23分钟前 发表
文件名包含了程序名(%e)