当前位置: 首页 > article >正文

【linux学习指南】Linux进程信号产生(三) 硬件异常除零出错?野指针异常?core文件

请添加图片描述

文章目录

  • 📝前言
  • 🌠模拟除0
    • 🌉除0出错?
    • 🌉野指针异常?
  • 🌠⼦进程退出coredump
    • 🌉Core Dump
  • 🚩总结


📝前言

硬件异常被硬件以某种⽅式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执⾏了除以0的指令,CPU的运算单元会产⽣异常,内核将这个异常解释为SIGFPE信号发送给进程。再⽐如当前进程访问了⾮法内存地址,MMU会产⽣异常,内核将这个异常解释为SIGSEGV信号发送给进程。

🌠模拟除0

在这里插入图片描述

#include <iostream>
#include <string>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>

int main()
{
    if(fork() == 0)
    {
        sleep(1);
        int a = 10;
        a /= 0;

        exit(0);
    }

    int status = 0;
    waitpid(-1, &status, 0);

    printf("exit sinal: %d, core dump: %d\n", status&0x7F,(status>>7)&1);
    
    return 0;
}

在这里插入图片描述
在这里插入图片描述

🌉除0出错?

在这里插入图片描述

  1. 操作系统如何检测进程内部错误
    当进程执行指令时,CPU 硬件会在执行某些操作(如除法运算)的过程中检查操作数是否合法。以整数除法为例,CPU 的算术逻辑单元(ALU)在执行除法操作时,会检查除数是否为零。如果除数为零,这是一种非法的算术操作,硬件会自动触发一个异常条件。

整个程序的执行流程是

首先,在地址内存空间中加载好了代码和数据,开始:通过地址寄存器eax进行存储操作,存储10,存储时将寄存器ebx的值设为0CPU中存在一个状态寄存器,称为eFlags寄存器。

CPU的算术逻辑单元(ALU)在执行操作时,会检查除数是否为0。如果除数为0,这是一种非法操作,会触发异常条件。此时,硬件会将状态eFlags寄存器中的溢出标志位置为1

OS系统要不要知道CPU(硬件)内部出错了?
操作系统需要知道CPU内部出现了错误。它可以通过找到引发异常的进程,然后向该进程发送信号来终止该进程。但即使进程被杀死,其他进程仍需要进行调度和上下文切换等操作。

OS会说:谁把我的CPU搞坏了,接下来就要通过信号杀掉进程!,那OS怎么知道是哪个信号?此时进程中,我们把8号信号补捉了,但是我们进程没有立刻退出,立刻被杀掉!因为进程还需要进行被OS调度:切换(保存上下文数据),进行(比如后续的代码操作)等等

当这个异常进程被杀死前,OS需要保存上下文数据,保证下次再调用时恢复。因此,在上下文切换时,需要保存eax,ebx,ecx,eFlags等一系列寄存器的值。当保存好后,OS调度下一个进程,CPU寄存器只有一套,把上下文数据恢复进来,这时,Efalgs标志位被恢复,溢出标志位一直都是1~这个时候,这个进程又开始死循环异常

总结
无论OS需要等待该死循环进程结束后,进程假如后面还有代码,没有退出,再进行后面代码处理,Efalgs标志位,溢出标志位一直都是1~,一样死循环。当重新进来下一个进程,恢复执行时,上下文数据,Efalgs标志位被恢复,溢出标志位一直都是1,会再次触发异常,陷入死循环。

总的来说,这段描述了CPU发生除零错误时的异常处理流程,包括硬件触发异常、OS发现错误、终止异常进程,以及进程切换时上下文保存等步骤。整个过程涉及CPU硬件和操作系统的协作。

🌉野指针异常?

在这里插入图片描述
首先数据和代码在磁盘中,然后磁盘的随物理地址加载到物理内存中,物理内存中也有地址,这个地址为虚拟地址,页表右边是虚拟地址,左边是物理地址。pc存放的下一条执行指令的虚拟,经过pc指令传递给MMU硬件和CR3命令的处理,虚拟地址就可以找到页表的右边的物理地址,当除0这个指令传递给MMU去查页表时,访问0号地址,但是零号地址是无法访问的,这个时候MMU开始出错,一出错,找到这个进程,处理这个进程,进程还不能退出,后续代码也许需要执行,OS需要对进程进行调度,切换,执行,而MMU也有一套寄存器,当这个寄存器除以0出错之后,然后寄存器喵喵也会进行上下文的数据保存。保存之后,他就即使OS调度下一个进程,或者切换这个状态,寄存器状态一直同样也为一,MMU会一直报错,然后就会进程异常终止,但一直没退出。

总结
由此可以确认,我们在C/C++当中除零,内存越界等异常,在系统层⾯上,是被当成信号处理的。

注意:
通过上⾯的实验,我们可能发现:
发现⼀直有8号信号产⽣被我们捕获,这是为什么呢?上⾯我们只提到CPU运算异常后,如何处理后续的流程,实际上OS会检查应⽤程序的异常情况,其实在CPU中有⼀些控制和状态寄存器,主要⽤于控制处理器的操作,通常由操作系统代码使⽤。状态寄存器可以简单理解
为⼀个位图,对应着⼀些状态标记位、溢出标记位。OS会检测是否存在异常状态,有异常存在就会调⽤对应的异常处理⽅法。

除零异常后,我们并没有清理内存,关闭进程打开的⽂件,切换进程等操作,所以CPU中还保留上下⽂数据以及寄存器内容,除零异常会⼀直存在,就有了我们看到的⼀直发出异常信号的现象。访问⾮法内存其实也是如此,⼤家可以⾃⾏实验。

🌠⼦进程退出coredump

在这里插入图片描述

int main()
{
    if(fork() == 0)
    {
        sleep(1);
        int a = 10;
        a /= 0;

        exit(0);
    }

    int status = 0;
    waitpid(-1, &status, 0);

    printf("exit sinal: %d, core dump: %d\n", status&0x7F,(status>>7)&1);

    return 0;
}

指令:wks@hcss-ecs-ab43:~/code/signal24$ man 7 signal

   Standard signals
       Linux supports the standard signals listed  be‐
       low.   The second column of the table indicates
       which standard (if any) specified  the  signal:
       "P1990"  indicates that the signal is described
       in the original POSIX.1-1990 standard;  "P2001"
       indicates  that  the  signal was added in SUSv2
       and POSIX.1-2001.
       "P1990"  indicates that the signal is described
       in the original POSIX.1-1990 standard;  "P2001"
       indicates  that  the  signal was added in SUSv2
       and POSIX.1-2001.

       Signal      Standard   Action   Comment
       ────────────────────────────────────────────────────────────────────────
       SIGABRT      P1990      Core    Abort signal from abort(3)
       SIGALRM      P1990      Term    Timer signal from alarm(2)
       SIGBUS       P2001      Core    Bus error (bad memory access)
       SIGCHLD      P1990      Ign     Child stopped or terminated
       SIGCLD         -        Ign     A synonym for SIGCHLD
       SIGCONT      P1990      Cont    Continue if stopped
       SIGEMT         -        Term    Emulator trap
       SIGFPE       P1990      Core    Floating-point exception
       SIGHUP       P1990      Term    Hangup detected on controlling terminal
                                       or death of controlling process
       SIGILL       P1990      Core    Illegal Instruction
       SIGINFO        -                A synonym for SIGPWR
       SIGINT       P1990      Term    Interrupt from keyboard
       SIGIO          -        Term    I/O now possible (4.2BSD)

       SIGIOT         -        Core    IOT trap. A synonym for SIGABRT
       SIGKILL      P1990      Term    Kill signal
       SIGLOST        -        Term    File lock lost (unused)
       SIGPIPE      P1990      Term    Broken pipe: write to pipe with no
                                       readers; see pipe(7)
       SIGPOLL      P2001      Term    Pollable event (Sys V);
                                       synonym for SIGIO
       SIGPROF      P2001      Term    Profiling timer expired
       SIGPWR         -        Term    Power failure (System V)
       SIGQUIT      P1990      Core    Quit from keyboard
       SIGSEGV      P1990      Core    Invalid memory reference
       SIGSTKFLT      -        Term    Stack fault on coprocessor (unused)
       SIGSTOP      P1990      Stop    Stop process
       SIGTSTP      P1990      Stop    Stop typed at terminal
       SIGSYS       P2001      Core    Bad system call (SVr4);
                                       see also seccomp(2)
       SIGTERM      P1990      Term    Termination signal
       SIGTRAP      P2001      Core    Trace/breakpoint trap
       SIGTTIN      P1990      Stop    Terminal input for background process
       SIGTTOU      P1990      Stop    Terminal output for background process
       SIGUNUSED      -        Core    Synonymous with SIGSYS
       SIGURG       P2001      Ign     Urgent condition on socket (4.2BSD)
       SIGUSR1      P1990      Term    User-defined signal 1
       SIGUSR2      P1990      Term    User-defined signal 2
       SIGVTALRM    P2001      Term    Virtual alarm clock (4.2BSD)
       SIGXCPU      P2001      Core    CPU time limit exceeded (4.2BSD);
                                       see setrlimit(2)
       SIGXFSZ      P2001      Core    File size limit exceeded (4.2BSD);
                                       see setrlimit(2)
       SIGWINCH       -        Ign     Window resize signal (4.3BSD, Sun)

       The  signals  SIGKILL  and  SIGSTOP  cannot  be
       caught, blocked, or ignored.

在这里插入图片描述

🌉Core Dump

在这里插入图片描述

  • SIGINT的默认处理动作是终止进程,SIGQUIT的默认处理动作是终止进程并且Core Dump,现在我们来验证一下。
  • ⾸先解释什么是CoreDump。当⼀个进程要异常终⽌时,可以选择把进程的⽤⼾空间内存数据全部保存到磁盘上,⽂件名通常是core,这叫做CoreDump。
  • 进程异常终⽌通常是因为有Bug,⽐如⾮法内存访问导致段错误,事后可以⽤调试器检查core⽂件以查清错误原因,这叫做Post-mortem Debug (事后调试)。
  • 一个进程允许产生多大的core文件取决于进程的Resource Limit(这个信息保存在PCB中)。默认是不允许产生core文件的,因为core文件中可能包含用户密码等敏感信息,不安全。
  • 在开发调试阶段可以用ulimit命令改变这个限制,允许产生core文件。首先用ulimit|命令改变shell进程的Resource Limit ,如允许core|文件最大为1024K: $ ulimit -c1024

在这里插入图片描述

core-file core :事后调试


🚩总结

请添加图片描述


http://www.kler.cn/a/417273.html

相关文章:

  • grafana面板配置opentsdb
  • BFS算法——广度优先搜索,探索未知的旅程(下)
  • 退格法记单词(类似甘特图)
  • 金蝶云星空k3cloud webapi报“java.lang.Class cannot be cast to java.lang.String”的错误
  • Golang 并发机制-6:掌握优雅的错误处理艺术
  • 71.StackPanel黑白棋盘 WPF例子 C#例子
  • 嵌入式Linux使用OpenGL ES
  • mac下Gpt Chrome升级成GptBrowser书签和保存的密码恢复
  • Java List.of()改写为jdk8
  • 金融量化模型的变革之路:探索未来智能交易的核心
  • 大语言模型(LLM)不平衡的内存使用问题;训练过程中 Transformer层1和Transformer层2的反向传播计算量差异
  • C语言实例_16之求不同位数为同一个数的和
  • Flutter:city_pickers省市区三级联动
  • npm install -g@vue/cli报错解决:npm error code ENOENT npm error syscall open
  • 下载SRA序列数据——ascp(前期草稿,未上传待更新)
  • 亚马逊自研大语言模型 Olympus 即将亮相,或将在 LLM 竞赛中掀起新波澜
  • Python `async def` 函数中使用 `yield` 和 `return` 的区别
  • ffmpeg 各版本号对应表格
  • uni-app 使用笔记
  • ctrl键和大写键互换解决方法
  • TYUT设计模式精华版
  • 简单获取json预览
  • 每天五分钟深度学习框架pytorch:卷积神经网络的搭建
  • 自然语言处理:基于BERT预训练模型的中文命名实体识别(使用PyTorch)
  • Python Web 开发:FastAPI 入门实战 —— HTTP 基础与 RESTful API 设计
  • Python学习笔记之IP监控及告警