【发布时间】:2017-04-19 05:11:39
【问题描述】:
我在随机时间收到分段错误。
我注册了信号,但发生分段错误时未调用信号处理程序
#include <unistd.h>
#include <dlfcn.h>
#include <iostream>
#include <signal.h>
#include <execinfo.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
using namespace std;
void Handler(int sig)
{
cout << "handler called " << strsignal(sig) << endl;
exit(1);
}
int main()
{
cout << "Testing crash !" << endl;
signal(SIGSEGV, Handler);
signal(SIGINT, Handler);
signal(SIGABRT, Handler);
for (int i = 0; i < 10; i++)
{
cout << i << " Before open" << endl;
void *handler = dlopen("/home/user/Test.so", RTLD_LAZY);
if (handler)
{
cout << i << " Before close" << endl;
dlclose(handler);
cout << i << " After close" << endl;
}
else
{
cout << "Error " << dlerror() << endl;
}
}
return 0;
}
输出:
运行1
Testing crash !
0 Before open
0 Before close
0 After close
1 Before open
1 Before close
Segmentation fault (core dumped)
运行2
0 Before open
0 Before close
0 After close
1 Before open
1 Before close
1 After close
Segmentation fault (core dumped)
问题是没有调用信号处理程序来分析问题
【问题讨论】:
-
分段错误是 SIGSEGV。当你按下 Ctrl-C 时会触发 SIGINT。
-
当心 printf 缓冲行为;当代码崩溃时,您不应该使用 printf。或者,如果您这样做,也请调用 fflush(stdout)。
-
@PaulStelian printf/fflush 都不是async safe functions,根本不应该在信号处理程序中使用!
-
奇怪的是第二次运行。分段错误似乎出现在您自己的代码中 - 但这可能是一个缓冲问题。我建议在最后的每个输出中添加
<< std::flush以排除这种可能性。然后我会附加一个调试器以至少查看 where 发生分段错误。这可能会提供额外的提示。我个人试图产生一种无限循环,在 信号处理程序中重新创建段错误 - 但我显然没有得到第二个信号。
标签: c++ c linux embedded-linux