为什么这个信号处理程序被无限调用
我使用的是 Mac 操作系统 10.6.5,g++ 4.2.1。并遇到以下代码的问题:
#include <iostream>
#include <sys/signal.h>
using namespace std;
void segfault_handler(int signum)
{
cout << "segfault caught!!!\n";
}
int main()
{
signal(SIGSEGV, segfault_handler);
int* p = 0;
*p = 100;
return 1;
}
似乎 segfault_handler 被无限调用并继续打印:
发现段错误!!!
发现段错误!!!
发现段错误!!!
...
我是 Mac 开发新手,你知道发生了什么吗?
I am using Mac OS 10.6.5, g++ 4.2.1. And meet problem with following code:
#include <iostream>
#include <sys/signal.h>
using namespace std;
void segfault_handler(int signum)
{
cout << "segfault caught!!!\n";
}
int main()
{
signal(SIGSEGV, segfault_handler);
int* p = 0;
*p = 100;
return 1;
}
It seems the segfault_handler is called infinitely and keep on print:
segfault caught!!!
segfault caught!!!
segfault caught!!!
...
I am new to Mac development, do you have any idea on what happened?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是因为在信号处理程序执行后,EIP 返回到导致 SIGSEGV 的指令 - 因此它再次执行,并再次引发 SIGSEGV。
通常像你一样忽略 SIGSEGV 是没有意义的 - 假设指令实际上从指向寄存器的指针读取一些值,你会做什么?您没有任何“正确”值可放入寄存器中,因此以下代码可能会再次出现 SIGSEGV,或者更糟糕的是,触发一些逻辑错误。
您应该在 SIGSEGV 发生时退出进程,或者返回到已知的安全点 - longjmp 应该可以工作,如果您知道这确实是安全点(想到的唯一可能的例子是 VM口译员/JIT)。
This is because after your signal handler executes, the EIP is back to the instruction which causes the SIGSEGV - so it executes again, and SIGSEGV is raised again.
Usually ignoring SIGSEGV like you do is meaningless anyway - suppose the instruction actually read some value from a pointer to a register, what would you do? You don't have any 'correct' value to put in the register, so the following code will likely SIGSEGV again or, worse, trigger some logic error.
You should either exit the process when SIGSEGV happens, or return to a known safe point - longjmp should work, if you know that this is indeed the safe point (the only possible example that comes to mind is VM interpreters/JITs).
您是否尝试过在程序中返回 0 而不是 1?传统上,0 以外的值表示错误。另外,删除处理 *p 的两行可以解决这个问题吗?
Have you tried returning 0 instead of 1 in your program? Traditionally, values other than 0 indicate error. Also, does removing the two lines dealing with *p resolve it?