如果我捕捉到SIGSEGV,并且信号处理程序导致了另一个SIGSEGV,会发生什么?

编程入门 行业动态 更新时间:2024-10-19 08:54:16
本文介绍了如果我捕捉到SIGSEGV,并且信号处理程序导致了另一个SIGSEGV,会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

这个问题是在考虑Linux的情况下提出的.使用了GCC编译器.

This question is asked with Linux in mind. GCC compiler is used.

如果在旨在捕获SIGSEGV的信号处理程序中发生SIGSEGV(通常是导致SIGSEGV的违规),将会发生什么行为?有助于讨论的代码示例:

What behaviour can be expected if SIGSEGV (I mean a violation that normally causes SIGSEGV) occurs within a signal handler whose purpose was to catch SIGSEGV? Code example to aid the discussion:

/* In main or whatever */ { struct sigaction sa = {}; /* initialised to all zero (I vote for GCC style breach of standard here) */ sa.sa_handler = DisasterSignals; sa.sa_flags = SA_RESETHAND | SA_NODEFER; /* To have or have not */ sigaction(SIGSEGV, &sa, NULL); } static void DisasterSignals(int signal) { /* We cannot save the situation, the purpose of catching the signal is only to do something clever to aid debugging before we go. */ /* Q: What if we segfault in here?? */ abort(); /* This should give us the expected core dump (if we survive to this point) */ }

想象一下,在点Q"处,有一条违规的机器指令.

Imagine, in the point "Q", There is an offending machine instruction.

1)没有 SA_RESETHAND |SA_NODEFER :这似乎使系统陷入逻辑陷阱:在"Q"处,应生成SIGSEGV.但是SIGSEGV在信号处理程序中被阻止(默认sigaction行为).如何继续执行?会冻结吗?它会跳过违规指令(我想不是)吗?

1) Without the SA_RESETHAND | SA_NODEFER: This appears to put the system in a logical trap: At "Q", SIGSEGV should be generated. But SIGSEGV is blocked in the signal handler (default sigaction behaviour). How can the execution continue? Will it freeze? Will it jump past the offending instruction (I guess not)?

2)使用 SA_RESETHAND |SA_NODEFER :我想在这种情况下,当重复SIGSEGV时,程序将以正常"方式崩溃.

2) With the SA_RESETHAND | SA_NODEFER: I guess in this case the program will crash in a "normal" fashion when SIGSEGV is repeated.

3)仅使用 SA_NODEFER :我想在这种情况下,当重复SIGSEGV时,将递归调用信号处理程序.如果始终重复执行SIGSEGV,我们将冻结直到堆栈溢出为止.

3) With only SA_NODEFER: I guess in this case the signal handler is recursively called when SIGSEGV is repeated; if the SIGSEGV is always repeated, we get a freeze until the stack overflows, and then what.

推荐答案

默认情况下,正在处理信号时将其屏蔽,因此无法递归触发它.如果屏蔽信号是由程序执行触发的(无效的内存访问,segfault,除以0等),则该行为是不确定的:

By default, while signal is being handled it is masked, so it can't be triggered recursively. If masked signal is triggered by program execution (invalid memory access, segfault, division by 0 etc.), the behavior is undefined:

如果在生成SIGBUS,SIGFPE,SIGILL或SIGSEGV的同时阻止,结果是不确定的,除非信号是由kill(2),sigqueue(3)或raise(3).

If SIGBUS, SIGFPE, SIGILL, or SIGSEGV are generated while they are blocked, the result is undefined, unless the signal was generated by kill(2), sigqueue(3), or raise(3).

在我的系统上,它导致进程崩溃.

On my system, it causes process to crash.

使用 SA_NODEFER 没有屏蔽,因此可以递归处理信号,直到堆栈溢出为止.添加 SA_RESETHAND 将恢复默认操作(SIGSEGV崩溃).

With SA_NODEFER there is no masking, so signal can be handled recursively until stack overflows. And adding SA_RESETHAND would restore default action (crash for SIGSEGV).

我将您的示例改编为简单的测试程序,因此您可以验证此行为:

I adapted your example to simple testing program, so you can verify this behavior:

#include<signal.h> #include<stdio.h> #include<stdlib.h> #include<unistd.h> volatile char *ptr; static void DisasterSignals(int signal) { /* We cannot save the situation, the purpose of catching the signal is only to do something clever to aid debugging before we go. */ write(1, "11\n", 3); *ptr = 1; write(1, "13\n", 3); abort(); /* This should give us the expected core dump (if we survive to this point) */ } struct sigaction sa = {}; /* initialised to all zero (I vote for GCC style breach of standard here) */ int main() { sa.sa_handler = DisasterSignals; sa.sa_flags = /*SA_RESETHAND | */SA_NODEFER; /* To have or have not */ sigaction(SIGSEGV, &sa, NULL); write(1, "25\n", 3); *ptr = 1; }

更多推荐

如果我捕捉到SIGSEGV,并且信号处理程序导致了另一个SIGSEGV,会发生什么?

本文发布于:2023-10-09 05:57:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1474896.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:捉到   信号处理   发生   程序   SIGSEGV

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!