文章目录
目录
前言
上一篇博客讲解了3种创建信号的方式
1、键盘输入的方式;比如ctrl+c等
2、系统调用接口;kill、raise、 abort这3个接口
3、命令行;kill -9 pid
这篇再介绍最后两种方式
一、创建进程的信号
回忆前三种常见信号方式
1、键盘输入方式
在进程运行时,我们输入ctrl+c(2号型号)依次方式获得信号;
2、系统接口
3、指令获得信号
在我们进程在运行时,我们输入指令加上所需要的信号再加需要接受信号的pid即可;
现在我们学习信号获得信号方式
4、硬件异常产生信号
我们在学习c语言、c++还有java时,我们接触过异常这个概念,我们知道被除数不可以为0,还有野指针的存在,一但出现就会出现抛异常,抛了异常进程就会崩溃。
那么为什么出现除零和野指针会让进程奔溃呢?
- 当 CPU 执行到除零操作时,如前所述,硬件(算术逻辑单元 ALU)会检测到这个非法的算术运算。除了可能将状态寄存器的相关标志位(如在某些架构中的溢出标志位或特定的算术异常标志位)置位来表示出现了异常情况外,CPU 会暂停当前指令序列的正常执行流程。这是因为除零操作在数学上是无定义的,硬件无法按照正常的算术规则完成这个运算。
- 然后产生溢出标识位,操作系统检查到让进程奔溃。
- 硬件会产生一个中断信号来通知操作系统内核发生了异常。这个中断信号携带了关于异常类型(除零异常)的基本信息。在 x86 架构中,通过中断向量表(IDT - Interrupt Descriptor Table)来确定如何处理这个中断。当这个除零异常对应的中断向量被触发时,CPU 会跳转到内核预先设置好的中断处理程序入口点。
- 内核的中断处理程序会获取硬件传递过来的异常信息,包括异常发生的指令地址(通过 CPU 的一些寄存器,如在 x86 架构中的 CS 和 EIP 寄存器组合可以确定异常指令的位置)和异常类型代码。内核根据这些信息来确定是哪个进程触发了这个除零异常。
- 对于除零异常,在 Linux 系统中,内核会生成一个
SIGFPE
(浮点异常信号)信号。然后,内核通过进程控制块(PCB)找到与触发异常的进程相关的信息,将SIGFPE
信号发送给该进程。 - 如果进程没有为
SIGFPE
信号注册自定义的信号处理程序,那么操作系统会采用默认的信号处理方式。默认情况下,这个信号会导致进程终止。这是因为除零错误通常被认为是一个严重的错误,表明程序的逻辑出现了问题。而且,继续执行可能会导致不可预测的结果,所以操作系统选择终止进程来防止可能出现的更严重的问题,如数据损坏或系统不稳定。同时,如果系统配置允许,操作系统可能会生成一个核心转储文件(core dump)。这个文件包含了进程在崩溃瞬间的内存映像、寄存器状态等信息,用于后续的调试,以帮助开发者确定除零错误发生的具体原因。
只有操作系统可以管理进行和硬件,cup只是硬件,不可以管理进程和cpu;
我们只需要知道标黄色部分的过程即可;
代码及操作示范
#include<iostream>
#include<unistd.h>
#include<signal.h>
using namespace std;
int main()
{
int x=4;
int a=x/0;
return 0;
}
我们man 7 signal查看报错码,发现是8号指令