【Linux】进程信号篇Ⅰ:信号的产生(signal、kill、raise、abort、alarm)、信号的保存(core dump)

news2024/9/23 3:26:15

文章目录

  • 一、 signal 函数:用户自定义捕捉信号
  • 二、信号的产生
    • 1. 通过中断按键产生信号
    • 2. 调用系统函数向进程发信号
      • 2.1 kill 函数:给任意进程发送任意信号
      • 2.2 raise 函数:给调用进程发送任意信号
      • 2.3 abort 函数:给调用进程发送 6 号信号
    • 3. 软件条件产生信号
      • alarm 函数:闹钟时间后,发送 14(SIGALRM )号信号
    • 4. 硬件异常产生信号
      • 4.1 除0:8) SIGFPE
      • 4.2 野指针:11) SIGSEGV
  • 三、信号保存的细节
    • 1. core 和 term
    • 2. waitpid 中,status 第八位的 core dump 标志位
  • 🔗 接下篇


kill -l 可以查看所有信号:

在这里插入图片描述
其中,前面的数字就是信号,后面的大写英文就是信号名称,实际就是宏。

我们需要关注的是 1~31 号普通信号,关注他们有没有产生(可以用 0 或者 1 表示)。

所以,进程的 pcb 中,需要对产生的信号先用 位图 保存起来,再按照一定的顺序去处理他们。

我们所谓发送信号,本质其实就是写入信号,直接修改特定进程的信号位图中的特定比特位(0 / 1)。位图中,比特位的位置,是信号的编号;比特位的内容表示,是否收到该信号。

无论后面有多少种信号产生的方式,最终都必须要让 OS 来完成最后发送 / 写入的过程。

man 7 signal:查看所有信号详细信息
在这里插入图片描述


一、 signal 函数:用户自定义捕捉信号

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

参数 signum:

  • 信号编号


参数 handler:

  • 用户自定义处理动作,在 signum 信号发生时触发。

🌰使用举例:

// 自定义方法
// signo:特定信号被发送给当前进程的时候,执行handler方法的时候,要自动填充对应的信号给handler方法
// 我们甚至可以给所有的信号设置同一个处理函数
void handler(int signo)
{
    std::cout << "get a singal: " << signo << std::endl;
    // exit(2);
}


int main()
{
    // signal(SIGINT, handler);
    // signal(SIGQUIT, handler);

    signal(2, handler);	// 2:ctrl+c
    signal(3, handler);	// 3:ctrl+\
    while(true)
    {
        std::cout << "我是一个进程,我正在运行 ..., pid: " << getpid() << std::endl;
        sleep(1);
    }

    return 0;
}
1. 2号信号,进程的默认处理动作是终止进程
2. signal 可以进行对指定的信号设定自定义处理动作
3. signal(2, handler)调用完这个函数的时候,handler方法没有被调用,只是更改了2号信号的处理动作。
4. 那么handler方法在当2号信号产生的时候才会被调用
5. 默认我们对2号信号的处理动作:终止进程,我们用signal(2, handler), 我们在执行用户动作的自定义捕捉!不是每个信号我们都可以自定义捕捉的!!比如 9 就不行。是 OS 规定的

二、信号的产生

1. 通过中断按键产生信号

比如用户按下 ctrl+c,键盘输入产生一个 硬件中断,用电信号将中断号写入寄存器,系统再根据中断号去中断向量表中查找,然后 OS 再从键盘中去读取数据(看是键盘哪些位置被摁下)。被 OS 获取后,解释成信号,发送给目标前台进程。

2. 调用系统函数向进程发信号

2.1 kill 函数:给任意进程发送任意信号

头文件

#include <signal.h>

int kill(pid_t pid, int sig);

参数 pid:

  • 进程pid

参数 sig:

  • 信号

2.2 raise 函数:给调用进程发送任意信号

头文件

#include <signal.h>

int raise(int sig);

参数 sig:

  • 信号

2.3 abort 函数:给调用进程发送 6 号信号

头文件

#include <stdlib.h>

void abort(void);

进程收到 6 号信号就会终止,即使可以被用户捕捉到,也会完成终止。

3. 软件条件产生信号

(SIGPIPE也是一个由软件条件产生的信号

alarm 函数:闹钟时间后,发送 14(SIGALRM )号信号

默认动作是终止(Term)当前进程
头文件

#include <unistd.h>

unsigned alarm(unsigned seconds);

参数 seconds:

  • 时间


返回值:

  • 0,或者是以前设定的闹钟时间还余下的秒数。(比如第一次提前结束,在次重新设定时,就会返回之前剩余的时间)

alarm 函数是一次性的,可以利用捕捉器,进行 自取 操作,达到不断设置闹钟的作用。

🌰使用举例:

void myhandler(int signo)
{
    std::cout << "get a signal: " << signo << " count: " << count << std::endl;
    alarm(1);
    // exit(0);
}

int main(int argc, char *argv[])
{
    std::cout << "pid: " << getpid() << std::endl;
    signal(SIGALRM, myhandler);
    alarm(1); //一次性的

    while(true)
    {
        sleep(1);
    }
}

alarm 也是有内核数据结构的,OS 管理这些内核数据结构,每隔一段时间就会去比如说管理 alarm 的最小堆中,当堆顶 timestamp >= 系统当前时间 时,就会给这个对应的进程 pid 发送 SIGALRM 信号,并把这个闹钟从堆中拿走。

struct alarm
{
	int timestamp; // curr + 设置的seconds
	// ...进程 pid ...等等
};

4. 硬件异常产生信号

硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。

4.1 除0:8) SIGFPE

SignalValueActioncomment
SIGFPE8CoreFloating point exception

例如当前进程执行了除 0 的指令,CPU的运算单元会产生异常,内核将这个异常解释为 SIGFPE 信号,发送给进程。

状态寄存器:用比特位表示状态,其中有一位,就是反映本次计算是否有溢出问题。

出现除 0 后,溢出标志位被置 1,os 发现后立即将 相应进程 pcb 中发送 8号 信号。

4.2 野指针:11) SIGSEGV

SignalValueActioncomment
SIGSEGV11CoreInvalid memory reference

再比如当前进程访问了非法内存地址,MMU 会产生异常,内核将这个异常解释为 SIGSEGV 信号发送给进程。

虚拟地址 通过页表 转换访问到物理内存,这个过程其实是软硬件结合的方式完成的。这个页表的 KV 转换过程就是由硬件 MMU 完成的。

MMU:内存管理单元,被集成在 CPU 内,转换时,只需要把虚拟地址导入到 MMU 这个硬件中,用这个硬件转。

🌰举例:

// 一个野指针问题
int *p = nullptr;
p* = 100;

分析上述代码,当我们赋值给指针为 nullptr 时,p 里面放的是 0 或者 nullptr,*p 代表的就是虚拟地址空间中的 0 号地址,我们想将 100 写入 0 号地址,但这个地址我们没有申请过,他也不允许我们访问,所以造成了野指针 / 悬垂指针问题。

其实,*p = 100;第一步并不是写入,而是首先进行虚拟地址到物理内存的转换。

  • 没有映射:MMU 硬件报错
  • 有映射,但是没有权限:MMU 直接报错
  • OS 接收到报错后,传递给 CPU 中的一个寄存器,找到相应进程的 pcb 对其发送 11号 信号。

三、信号保存的细节

1. core 和 term

查看信号的 Action 栏有 core 和 term 两种。

他们有什么不同呢?

在这里插入图片描述

  • term 终止的就是终止,没有多余的动作。

  • core 终止,会先进行核心转储,再进行终止。

进程在异常的时候,OS 可以将该核心代码部分进行 核心转储,将内存中进程的相关数据,全部 dump 到磁盘中。核心转储的目的是,方便异常后进行调试。

一般核心转储文件在云服务器上确实看不到,而是云服务器默认是关闭这个功能的!ulimit -a 可以查到 core_file_size 大小是0,即关闭的,按照提示 ulimit -c [数值] 设置大小,即可打开核心转储功能,数值设为 0 就是关闭。

当程序异常时,我们不知道哪里出了问题。有如下解决方法,称作 事后调试

  • -g 生成可执行程序,使用 gdb 命令打开调试模式

  • 命令行中输入:core-file core.xxxx (xxxx 为相应的核心转储生成文件),就会出现报错原因的详细信息,和报错位置

既然核心转储那么方便,为什么云服务器要关闭这个功能呢?

Linux环境根据使用目的可以分为:开发环境、测试环境、生产环境
云服务器属于生产环境,生产环境是默认关闭核心转储的!

按照 CPU 的运行速度,错误的代码,在短时间内可以造成大量的 core. 文件,磁盘写满甚至系统崩溃都是有可能的,所以生产环境下,一般都是将这个功能关闭的。

2. waitpid 中,status 第八位的 core dump 标志位

在这里插入图片描述

这里的 core dump 标志位,就是用来记录,是否有 core dump 出现的。



🔗 接下篇

👉🔗进程信号篇Ⅱ:信号的阻塞及保存(sigset_t, sigprocmask, sigpending)、信号的处理、信号的捕捉(sigaction)

👉🔗进程信号篇Ⅲ:可重入函数、volatile关键字、SIGCHLD信号


🥰如果本文对你有些帮助,请给个赞或收藏,你的支持是对作者大大莫大的鼓励!!(✿◡‿◡) 欢迎评论留言~~



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/901410.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

域名解析和代理

购买域名 这里使用腾讯云进行购买。 对域名进行解析 通过添加记录接口对域名进行解析。 此时我们的服务器地址就被解析到域名上了。 我们可以通过以下格式进行访问&#xff1a; [域名]:[对应的项目端口] 效果为下: 通过nginx进行代理 如果我们使用上述的方式进行访问还是…

轻松搭建书店小程序

在现今数字化时代&#xff0c;拥有一个自己的小程序成为了许多企业和个人的追求。而对于书店经营者来说&#xff0c;拥有一个能够提供在线购书服务的小程序将有助于吸引更多的读者&#xff0c;并提升销售额。本文将为您介绍如何轻松搭建书店小程序&#xff0c;并将其成功上线。…

Spring事件监听源码解析

spring事件监听机制离不开容器IOC特性提供的支持&#xff0c;比如容器会自动创建事件发布器&#xff0c;自动识别用户注册的监听器并进行管理&#xff0c;在特定的事件发布后会找到对应的事件监听器并对其监听方法进行回调。Spring帮助用户屏蔽了关于事件监听机制背后的很多细节…

Spring事务和事务传播机制(1)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 在Spring框架中&#xff0c;事务管理是一种用于维护数据库操作的一致性和…

HLK-LD105/2410B/2420模块测试

HLK105/2410B/2420模块测试 &#x1f4cc;模块资料地址&#xff1a;https://h.hlktech.com/Mobile/download &#x1f33f;HLK-LD105模块&#xff1a; 10G微波雷达 &#x1f33f;HLK-LD2420-24G&#xff1a;24G毫米波雷达 &#x1f33f;HLK-LD2410B-24G&#xff1a;24…

网络安全--wazuh环境配置及漏洞复现

目录 一、wazuh配置 二、wazuh案例复现 一、wazuh配置 1.1进入官网下载OVA启动软件 Virtual Machine (OVA) - Installation alternatives (wazuh.com) 1.2点击启动部署&#xff0c;傻瓜式操作 1.3通过账号&#xff1a;wazuh-user&#xff0c;密码&#xff1a;wazuh进入wazuh…

【NOIP】XR-4模拟赛,Oler教练的上班策略

author&#xff1a;&Carlton tag&#xff1a;模拟 topic&#xff1a;【NOIP】XR-4模拟赛&#xff0c;Oler教练的上班策略 language&#xff1a;C website&#xff1a;洛谷 date&#xff1a;2023年8月19日 目录 题目 我的题解 思路 源代码 改进 题目 我的题解 思路…

iptables防火墙(SNAT与DNAT)

目录 1 SNAT 1.1 SNAT原理与应用 1.2 SNAT工作原理 1.3 SNAT转换前提条件 2 SNAT示例 ​编辑 2.1 网关服务器配置 2.1.1 网关服务器配置网卡 2.1.2 开启SNAT命令 2.2 内网服务器端配置 2.3 外网服务器端配置 2.4 网卡服务器端添加规则 2.5 SNAT 测试 3 DNAT 3.1 网卡…

Windows 11 下使用 VMWare Workstation 17 Pro 新建 CentOS Stream 9 64位 虚拟机 并配置网络

文章目录 为什么选择 CentOS Stream 9下载安装访问连接快照克隆网络配置 为什么选择 CentOS Stream 9 CentOS Linux 8: 已经过了 End-of-life (EOL)CentOS Linux 7: EOL Jun 30th, 2024CentOS Stream 8: EOL May 31st, 2024CentOS Stream 9: End of RHEL9 full support phase …

DTC 19服务学习1

在UDS&#xff08;统一诊断服务&#xff09;协议中&#xff0c;0x19是用于DTC&#xff08;诊断故障代码&#xff09;信息的服务。以下是你提到的子服务的功能和作用&#xff1a; 0x01 - 报告DTC按状态掩码。这个子服务用于获取当前存储在ECU中的DTC列表。状态掩码用于过滤DTC&a…

redis闪退的三大解决办法(windows版本)

目录 一、遇到问题 二、出现问题的原因 三、三大启动方法 &#xff08;一&#xff09;启动服务端的命令一 &#xff08;二&#xff09;启动服务端命令二 &#xff08;三&#xff09;必解决redis服务端 一、遇到问题 下载完成redis的5的版本&#xff0c;要进行启动redis的…

UML基础模型

目录 1.抽象类2.接口3.继承4.实现接口5.关联关系6.聚合关系7.合成&#xff08;组合&#xff09;关系8.依赖关系 1.抽象类 矩形框代表一个类&#xff08;Class&#xff09;。 类图分为三层&#xff1a; 第一层显示类的名称&#xff0c;如果是抽象类&#xff0c;就用斜体显示&am…

kafka--kafka基础概念-ISR详解

kafka基础概念-ISR详解 主要是讲 主 往 从同步中的问题 当绿色P1接收到写入的数据&#xff0c;要同步到紫色的P1S1和P1S2 如何保证一致性呢&#xff1f; 使用In Sync Replicas 也就是ISR概念 为什么不一致的&#xff1f; 因为P1S1同步数据 可能花费 50ms P1S2可能花费60ms…

G0第26章:微服务概述与gRPCprotocol buffers

Go微服务与云原生 1、微服务架构介绍 单体架构&#xff08;电商&#xff09; SOA架构&#xff08;电商&#xff09; 微服务架构&#xff08;电商&#xff09; 优势 挑战 拆分 发展史 第一代:基于RPC的传统服务架构 第二代:Service Mesh(istio) 微服务架构分层 核心组件 Summar…

云安全与多云环境管理:讨论在云计算和多云环境下如何保护数据、应用程序和基础设施的安全

随着云计算和多云环境的广泛应用&#xff0c;企业正面临着数据、应用程序和基础设施安全的新挑战。在这个数字化时代&#xff0c;保护敏感信息和业务运作的连续性变得尤为重要。本文将深入探讨在云计算和多云环境下如何有效地保护数据、应用程序和基础设施的安全。 章节一&…

【Teamcity 安装及入门使用】

Teamcity 安装及入门使用 前言安装无Mysql版本有Mysql版本 启动创建超管用户账户和密码忘记密码结尾语 前言 前不久&#xff0c;teamcity更新了2023.05.2版本&#xff0c;我对teamcity也有一段时间的学习了&#xff0c;所以想写一篇博客来记录一下这段时间的学习过程。 teamc…

这是我的纪念日

我的1460天 写这篇文章&#xff0c;是为了纪念自己这一千多个日日夜夜&#xff0c;我的热爱总算有了回报。 每次看到有小伙伴点赞&#xff0c;评论的时候&#xff0c;我都很开心&#xff0c;我知道自己的选择是正确的&#xff0c;我喜欢分享自己的所见所学&#xff0c;我也很…

7-3 数字加密

分数 15 全屏浏览题目 切换布局 作者 陈建海 单位 浙江大学 输入一个四位数&#xff0c;将其加密后输出。方法是将该数每一位上的数字加9&#xff0c;然后除以10取余&#xff0c;做为该位上的新数字&#xff0c;最后将千位和十位上的数字互换&#xff0c;百位和个位上的数字…

vue-element-admin新增view后点击侧边栏加载慢问题

按照官网文档新增view 新增之后点击显示一直在加载中 解决方案&#xff1a;删除script中这段代码

【自创】关于前端js的“嵌套地狱”的遍历算法

欢迎大家关注我的CSDN账号 欢迎大家关注我的哔哩哔哩账号&#xff1a;卢淼儿的个人空间-卢淼儿个人主页-哔哩哔哩视频 此saas系统我会在9月2号之前&#xff0c;在csdn及哔哩哔哩上发布成套系列教学视频。敬请期待&#xff01;&#xff01;&#xff01; 首先看图 这是我们要解…