【Linux】进程信号中的 core dump 标记位

简介: 【Linux】进程信号中的 core dump 标记位

一、什么是core dump

我们知道所有的程序最终运行起来,都会变成进程,进程在运行时可能会异常终止或崩溃,而Linux操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成核心转储)。

保存的这个文件通常是:该进程的同目录下以core.PID的方式命名的文件。

二、core dump的使用

1、开启core dump

在Linux下core dump选项一般是被关闭的,我们可以通过ulimit -a查看当前Linux下系统资源的限制。

可以看到,core file size的大小是0,这说明系统不允许我们生成core file文件 ,我们可以使用命令设置生成的core file文件的大小的最大限制。

ulimit -c 10240

可以看到使用此命令以后我们生成的core file文件的大小的最大限制就变为了10240 blocks了。

2、生成core file文件

在Linux下有很多信号我们可以使用kill -l查看:

kill -l

但是并不是所有的信号引起的退出都会产生core file文件,只有有core标志的信号引起的退出才会产生core file文件,我们可以通过 man 7 signal 查看信号的详细信息

man 7 signal

11 号信号SIGSEGV是一个段错误的信号,当你的进程有内存越界等问题时,通常会收到该信号,可以看到该信号是有core标志的。

2号信号SIGINT其实就是我们常用的Ctrl + C 键产生的信号,可以看到该进程是没有core标志的

下面我们用代码来验证:

#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
    while (true)
    {
        cout << "我是一个正在运行的进程..." << endl;
        sleep(1);
    }
    return 0;
}

对于这个死循环代码我们使用Ctrl + C 来进行终止,观察是否有core file文件的产生。

可以看到并没有core file文件的生成。

我们再来看下面的代码:

#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
    int* p = nullptr;
    *p = 10;
    cout << "野指针问题" << endl;
    return 0;
}

很明显这里会收到SIGSEGV信号,而SIGSEGV是有core标志的,因此此进程运行完毕以后应该生成core file文件。

运行结果:

可以看到确实生成了core file文件,我们打开该文件:

发现是乱码,这时因为core file里面是数据都是内存中的二进制数据,我们不使用特殊编码是看不懂里面的含义的。

3、验证进程退出码里面的core dump标志位

在以前我们学习进程等待时一定学习过:对于一个存储了进程的退出码的变量,其内部结构是这样的: 次第8位表示退出码,最低7位表示终止信号,终止信号的前一位就是core dump标志位。

按照这样的结构,如果我们创建一个子进程,让子进程直接遇到野指针收到SIGSEGV信号直接退出,然后我们在父进程里面检查core dump的标志位是否被置为1

#include <iostream>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;
int main()
{
    pid_t id = fork();
    if (id == 0)
    {
        // 子进程
        int* p = nullptr;
        *p = 10;
        cout << "野指针问题" << endl;
        exit(0);
    }
    int status = 0;
    wait(&status);
    cout << "子进程的退出信号:" << (status & 0x7F) << endl;
    cout << "子进程的core dump标志位:" << ((status >> 7) & 0x1) << endl;
    return 0;
}

运行结果:

当然这个结果是在core dump被开启的条件下,那么我们将core dump关闭运行的结果还会一致吗?

我们继续实验:

运行同样的代码,结果是:

可以看到 core dump标志位被改为了0

结论

  1. 同样的程序,在core dump是否开启时会有不同的效果。
  2. 如果core dump开启,遇到有core 标志的信号,会进行核心转储,并且退出码里面的core dump 标志位会被置为1
  3. 如果core dump关闭,遇到有core 标志的信号,也不会进行核心转储,并且退出码里面的core dump 标志位始终置为0

三、 core dump的应用

因为core file 文件内部有进程退出时的内存中的相关信息 ,所以我们可以用这些信息在gdb里面进行调试我们的代码,注意调试的程序要以debug模式发布。

例如下面的代码生成的core file 文件:

#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
    int* p = nullptr;
    *p = 10;
    cout << "野指针问题" << endl;
    return 0;
}

我们在gdb里面进行调试,然后直接使用下面的命令,gdb就能直接帮我们找到问题的根源了,这种调试手段一般被称为事后调试

core-file core文件

相关文章
|
17天前
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
2月前
|
消息中间件 存储 网络协议
从零开始掌握进程间通信:管道、信号、消息队列、共享内存大揭秘
本文详细介绍了进程间通信(IPC)的六种主要方式:管道、信号、消息队列、共享内存、信号量和套接字。每种方式都有其特点和适用场景,如管道适用于父子进程间的通信,消息队列能传递结构化数据,共享内存提供高速数据交换,信号量用于同步控制,套接字支持跨网络通信。通过对比和分析,帮助读者理解并选择合适的IPC机制,以提高系统性能和可靠性。
255 14
|
1月前
|
存储 网络协议 Linux
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
78 34
|
13天前
|
Linux
Linux:守护进程(进程组、会话和守护进程)
守护进程在 Linux 系统中扮演着重要角色,通过后台执行关键任务和服务,确保系统的稳定运行。理解进程组和会话的概念,是正确创建和管理守护进程的基础。使用现代的 `systemd` 或传统的 `init.d` 方法,可以有效地管理守护进程,提升系统的可靠性和可维护性。希望本文能帮助读者深入理解并掌握 Linux 守护进程的相关知识。
28 7
|
12天前
|
Linux Shell
Linux 进程前台后台切换与作业控制
进程前台/后台切换及作业控制简介: 在 Shell 中,启动的程序默认为前台进程,会占用终端直到执行完毕。例如,执行 `./shella.sh` 时,终端会被占用。为避免不便,可将命令放到后台运行,如 `./shella.sh &`,此时终端命令行立即返回,可继续输入其他命令。 常用作业控制命令: - `fg %1`:将后台作业切换到前台。 - `Ctrl + Z`:暂停前台作业并放到后台。 - `bg %1`:让暂停的后台作业继续执行。 - `kill %1`:终止后台作业。 优先级调整:
32 5
|
12天前
|
Linux 应用服务中间件 nginx
Linux 进程管理基础
Linux 进程是操作系统中运行程序的实例,彼此隔离以确保安全性和稳定性。常用命令查看和管理进程:`ps` 显示当前终端会话相关进程;`ps aux` 和 `ps -ef` 显示所有进程信息;`ps -u username` 查看特定用户进程;`ps -e | grep &lt;进程名&gt;` 查找特定进程;`ps -p &lt;PID&gt;` 查看指定 PID 的进程详情。终止进程可用 `kill &lt;PID&gt;` 或 `pkill &lt;进程名&gt;`,强制终止加 `-9` 选项。
20 3
|
1月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
49 17
|
1月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
60 26
|
1月前
|
消息中间件 Linux C++
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
68 16
|
2月前
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
185 20