gpt4 book ai didi

c - SIGSEGV 不能被 sigaction 捕获两次

转载 作者:太空宇宙 更新时间:2023-11-03 23:38:39 24 4
gpt4 key购买 nike

以下代码在第二个 printf 处有段错误,而这应该得到处理 (setjmp)。请注意,每个 printf 都会由于错误的格式字符串而创建段错误。第一个段错误得到了正确处理,但第二个没有(在注释掉 printf 后运行代码不会出现段错误)。

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

static jmp_buf escapeCallJmpBuf;
static void sigsegv_handler(int signal, siginfo_t *info, void *context) {
longjmp(escapeCallJmpBuf, 1);
}

int main(int argc, char **argv) {
struct sigaction segvAction, segvActionOld;
segvAction.sa_handler = 0;
memset(&segvAction.sa_mask, 0, sizeof(segvAction.sa_mask));
segvAction.sa_flags = SA_SIGINFO;
segvAction.sa_sigaction = sigsegv_handler;
sigaction(SIGSEGV, &segvAction, &segvActionOld);

int res;

// Catch first segmentation fault
if (setjmp(escapeCallJmpBuf)) {
res = 1;
} else {
printf ("%s\n", 2); // This will segfault
res = 0;
}

// try to catch second segmentation fault
if (setjmp(escapeCallJmpBuf)) {
res = 2;
} else {
printf ("%s\n", 3); // This will segfault
res = 0;
}

sigaction(SIGSEGV, &segvActionOld, 0);
return res;
}

最佳答案

setjmplongjmp 不一定恢复信号掩码(取决于实现)。可能发生的情况是在处理完第一个 SIGSEGV 后,信号掩码恢复为默认值。所以第二个 SIGSEGV 没有被捕获,即默认操作发生而不是你的,这是退出进程。

您应该改用 sigsetjmpsiglongjmp

POSIX状态:

It is unspecified whether longjmp() restores the signal mask, leaves the signal mask unchanged, or restores it to its value at the time setjmp() was called.

并建议:

Applications whose behavior depends on the value of the signal mask should not use longjmp() and setjmp(), since their effect on the signal mask is unspecified, but should instead use the siglongjmp() and sigsetjmp() functions (which can save and restore the signal mask under application control).

此外,从信号处理程序跳转也有限制:

It is recommended that applications do not call longjmp() or siglongjmp() from signal handlers. To avoid undefined behavior when calling these functions from a signal handler, the application needs to ensure one of the following two things:

After the call to longjmp() or siglongjmp() the process only calls async-signal-safe functions and does not return from the initial call to main().

Any signal whose handler calls longjmp() or siglongjmp() is blocked during every call to a non-async-signal-safe function, and no such calls are made after returning from the initial call to main().

关于c - SIGSEGV 不能被 sigaction 捕获两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51765041/

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