gpt4 book ai didi

c - 收到 SIGSEGV 信号后的处理行为?

转载 作者:IT王子 更新时间:2023-10-29 00:38:07 25 4
gpt4 key购买 nike

我们最近了解了 UNIX 操作系统类中的信号。我们使用 C 来访问 unix API。

一个同学正在无所事事地解引用无效指针(指向未分配的内存或空指针),然后处理生成的 SIGSEGV 信号。他有一个代码块是这样的:

int* p;
int i = 0;
for (; i < 10; i++){
printf("Iteration %d\n", i);
p = i;
int n = *p;
}

然后他有一个简单的信号处理程序,可以简单地打印信号编号。最终发生的事情是程序会重复打印出它收到了一个数字为 11 的信号——一个 SIGSEGV 信号并且永远不会退出循环。我们的教授发现这种行为很奇怪,并表示他会调查。

根据我在互联网上进行的搜索,该行为似乎一点也不奇怪,因为在 SIGSEGV 的情况下,程序应该在处理接收到的信号后再次执行有问题的指令。然而,这种行为似乎没有在任何官方 UNIX 或 LINUX 文档中的任何地方记录。你们中的任何人都可以指出有关此类行为的文档的大体方向吗?

编辑:

信号处理程序是这样的:

void signal_handler(int signo)
{
printf("%d\n", signo);
}

将控制台输出重定向到生成如下内容的文件:

Iteration 0
11
11
11
11
11
... (only stopped if we sent it a SIGINT)

最佳答案

正如您找到的文档所说,操作系统对从 SIGSEGV 返回的响应是未定义的。特别是对于这个实例,这意味着相关的库标准没有定义它应该在哪里恢复,而是将它留给它正在运行的机器的确切细节。

从内存中 X86 派生机器将重新启动错误指令。但是,其他处理器会跳过该指令并继续执行下一条指令。一般来说,这两种方法都没有那么有用,因为它们都会产生非常奇怪的行为。

正如您可能从中猜到的那样,具体执行的操作通常取决于您运行的处理器。对于特定的处理器,页面错误响应(和其他错误)都是精确定义的,这包括如果您在错误堆栈帧上执行“返回”指令会发生什么。

一般来说,对于可移植程序,在 SIGSEGV 处理程序中唯一安全的做法是退出程序。但是,如果您非常非常小心不要在库调用或类似过程中捕获信号,则可以使用 setjmp/longjmp。

关于c - 收到 SIGSEGV 信号后的处理行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29184713/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com