- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
以下代码在第二个 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;
}
最佳答案
setjmp
和 longjmp
不一定恢复信号掩码(取决于实现)。可能发生的情况是在处理完第一个 SIGSEGV 后,信号掩码恢复为默认值。所以第二个 SIGSEGV 没有被捕获,即默认操作发生而不是你的,这是退出进程。
您应该改用 sigsetjmp
和 siglongjmp
。
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/
我在一些代码中看到以下用法: struct sigaction term_handler; // global variable without initialization ... sigacti
我正在做简单的 sigaction 示例来练习 C,但是当我尝试编译代码时,它声称 struct sigaction 不存在 [1]。 当我检查我生成的一些旧代码时,我发现我在文件的最顶部添加了一些
如果我们使用 sigaction 来定义一个信号处理程序,那为什么我们不需要重置处理程序呢?如果我们使用 signal(sig_no,handler_func)那么我们必须重置它。为什么是这样? #i
我正在学习信号并编写了一个简单的程序来处理它们。 所以我输入一个数字,然后使用 fork 创建一个进程。父进程应该将数字作为信号发送给子进程,然后 child_signal 处理程序应该将数字的平方作
我在 C++ 中对此类使用 sigaction 时遇到问题: class SerialHandler{ private: ... /* Action Handling
我有以下 sigaction 处理程序代码 void signal_term_handler(int sig) { int rc = async_lockf(pid_file, F_UNLCK
我正在使用 sigaction 作为信号,我正在为此使用一个简单的结构。我实际上是从手册页中获取的。有人可以向我解释结构中的第二行是做什么的吗?还有一个错误: error: expected decl
有没有办法用sigaction结构和函数只捕获一次信号?更具体地说,我想简单地重置为默认特定信号 (SIGINT)。是否有可能在处理程序中实现这一点? 编辑 所以,这样的事情是正确的: void si
我正在将程序的信号处理从 signal() 转换为 sigaction()。 根据UNIX spec struct sigaction 应该至少有 4 个成员; sa_handler、sa_mask、
我很难理解 sigaction() 的方式有效。 在 , sigaction 定义为 int sigaction(int sig, const struct sigaction *act, struc
我正在查看 sigaction 的手册页,最后我看到了以下行。 sigaction(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
在我下面的代码中,如果我将 old_act 声明为全局变量,那么程序可以正常工作。如果在 main 中声明: 如果使用 SA_RESTART,它工作正常 如果不使用 SA_RESTART,则会导致段错
我必须向进程发送两个信号,SIGUSR1 和 SIGUSR2,以便修改程序中的特定 bool 变量 (SIGUSR1 将其设置为 true,SIGUSR2 将其设置为 false)。所以我写了一个 s
我正要向我们这里的应用程序添加一个额外的信号处理程序,我注意到作者使用了 sigaction() 来设置其他信号处理程序。我打算使用 signal()。按照惯例,我应该使用 sigaction(),但
编译以下代码, struct sigaction sa; memset (&sa, 0, sizeof (sa)); sa.sa_handler = &handler; sigaction (SIGR
我有一个程序,它为 SIGSEGV 安装信号处理程序。在信号处理程序中(我 try catch 崩溃)我重新启动我的应用程序。 但是当我的应用程序复活时,它不再处理 SIGSEGV。 这是一个例子:
我注意到 sigaction 被定义为结构和函数(http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html):
每次收到 SIGINT 时,我都使用 sigaction() 执行操作。我见过的所有教程都使用这个原型(prototype)作为信号处理程序 void sig_handler(int sig); 有没
这个问题在这里已经有了答案: What is it with printf() sending output to buffer? (3 个答案) 关闭 3 年前。 我是 Unix 中信号的新手,这
我正在尝试以下信号处理程序,引用在线教程,但它似乎不起作用,我的代码有什么问题: #include #include #include #include #include typedef void (
我是一名优秀的程序员,十分优秀!