gpt4 book ai didi

C 信号(SIGSEGV)为什么会无限循环?

转载 作者:行者123 更新时间:2023-12-01 23:55:48 28 4
gpt4 key购买 nike

我正在玩信号,对此感到惊讶。为什么程序会无限循环?

#include <stdio.h>
#include <signal.h>

//I'm told that volatile tells the compiler not to cache the address of the pointer.
volatile int *i;
void seg_fault_handler(int TrapID)
{
i = malloc(sizeof(int));
puts("seg fault avoided");
}

int main()
{
signal(SIGSEGV, seg_fault_handler);
*i += 1;
return 0;
}

注意,我试图通过在处理程序中 mallocing i 来纠正问题(i 为 NULL),所以我的问题不在 this answer 中。 .

最佳答案

首先,正如您链接的问题中的一个答案所指出的,捕获实际的段错误并正常返回会导致 undefined behavior :

The behavior of a process is undefined after it returns normally from a signal-catching function for a SIGBUS, SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill(), sigqueue(), or raise().



因此,一切皆有可能。

二、 volatile你在这里不好吗。这是 gcc 为 *i += 1 生成的内容:
movl    i, %eax            ; Copy the value (i.e., address) stored in i to eax
movl i, %edx ; Copy the value (i.e., address) stored in i to edx
movl (%edx), %edx ; Copy the value at the address in edx into edx <--- segfault here
addl $1, %edx ; Add 1 to edx
movl %edx, (%eax) ; Store the value in edx to the address in eax

即使您声明 i volatile 本身( volatile int * volatile i; ),它不起作用。现在编译器实际上从 i 读取只有一次:
movl    i, %eax            ; Copy the value (i.e., address) stored in i to eax
movl (%eax), %edx ; Copy the value at the address in eax into edx <--- segfault here
addl $1, %edx ; Add 1 to edx
movl %edx, (%eax) ; Store the value in edx to the address in eax

从信号处理程序返回会导致重新执行段错误指令,但您对 i 的更改信号处理程序中的值不会影响 edx 中的值,因此它仍然会陷入无限循环。操作系统不知道 edx 中的值是如何产生的,并且不会为您重新计算它(在这种情况下,通过再次加载 i )。

关于C 信号(SIGSEGV)为什么会无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23946371/

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