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

【linux学习指南】linux进程信号产生(三) 硬件异常&&除零出错?&&野指针异常?&&core文件 -k8凯发国际

?前言

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

?模拟除0

代码语言:javascript代码运行次数:0运行复制

#include #include #include #include #include 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出错?

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

整个程序的执行流程是:

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

代码语言:javascript代码运行次数:0运行复制

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

代码语言:javascript代码运行次数:0运行复制

   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 :事后调试


?总结

以上就是【linux】linux进程信号产生(三) 硬件异常&&除零出错?&&野指针异常?&&core文件的详细内容,更多请关注非常游戏网【www.vycc.cn】其他相关内容。

相关推荐

网站地图