当前位置: 首页 > 知识库问答 >
问题:

分段故障处理

辛麻雀
2023-03-14

我有一个应用程序,我用它来捕捉任何分割错误或ctrl-c。使用下面的代码,我能够捕获分段错误,但是处理程序被一次又一次地调用。我怎样才能阻止他们。告诉你,我不想退出我的申请。我只是可以小心释放所有损坏的缓冲区。

可能吗?

void SignalInit(void )
{

struct sigaction sigIntHandler;

sigIntHandler.sa_handler = mysighandler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
sigaction(SIGSEGV, &sigIntHandler, NULL);

}

handler是这样的。

void mysighandler()
{
MyfreeBuffers(); /*related to my applciation*/
}

这里的分段故障信号,处理程序被多次调用,因为明显的MyFreeBuffers()给我释放已经释放的内存的错误。我只想免费一次,但仍然不想退出应用程序。

请帮忙。

共有3个答案

卫子平
2023-03-14

如果SIGSEGV再次触发,那么明显的结论是对MyfreeBuffers()的调用没有修复根本的问题(如果该函数真的只释放一些分配的内存,我不知道你为什么会这么认为)。

大致上,当试图访问不可访问的内存地址时,会触发一个SIGSEGV。如果不打算退出应用程序,则需要使该内存地址可访问,或者使用longjmp()更改执行路径。

马坚白
2023-03-14

我一点也不同意“不要抓住SIGV”这句话。

这是处理意外情况的一个很好的方法。使用与setjmp/longjmp相关的信号机制处理空指针(如malloc故障所示)比在代码中分发错误条件管理要干净得多。

但是请注意,如果您在SEGV上使用sigaction,您一定不要忘记在sa_flags中说SA_NODEFER-或者找到另一种方法来处理SEGV将触发您的处理程序曾经。

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

static void do_segv()
{
  int *segv;

  segv = 0; /* malloc(a_huge_amount); */

  *segv = 1;
}

sigjmp_buf point;

static void handler(int sig, siginfo_t *dont_care, void *dont_care_either)
{
   longjmp(point, 1);
}

int main()
{
  struct sigaction sa;

  memset(&sa, 0, sizeof(sigaction));
  sigemptyset(&sa.sa_mask);

  sa.sa_flags     = SA_NODEFER;
  sa.sa_sigaction = handler;

  sigaction(SIGSEGV, &sa, NULL); /* ignore whether it works or not */ 

  if (setjmp(point) == 0)
   do_segv();

  else
    fprintf(stderr, "rather unexpected error\n");

  return 0;
}
吕成业
2023-03-14

类似于SIGSEGV的默认操作是终止进程,但当您为其安装了处理程序时,它将调用您的处理程序来覆盖默认行为。但问题是,segfaulting指令可能会在处理程序完成后重试,如果您没有采取措施修复第一个seg故障,重试的指令将再次出错,并继续执行。

因此,首先找到导致SIGSEGV的指令,并尝试修复它(您可以在处理程序中调用类似于回溯()的东西,自己看看哪里出错了)

另外,POSIX标准说,

进程从[XSI]SIGBUS、SIGFPE、SIGILL或SIGSEGV信号的信号捕获函数正常返回后,其行为未定义,该信号不是由kill()、[RTS]sigqueue()或raise()生成的。

所以,理想的做法是首先修复你的分段故障。处理程序不是为了绕过潜在的错误条件

所以最好的建议是-不要抓住SIGSEGV。让它倾倒核心。分析核心。修复无效的内存引用,就这样!

 类似资料:
  • 问题内容: 我有一个用于捕获任何分段错误或ctrl- c的应用程序。使用下面的代码,我能够捕获分段错误,但是该处理程序一次又一次地被调用。我该如何阻止他们。供您参考,我不想退出我的申请。我只是可以小心释放所有损坏的缓冲区。 可能吗? 处理程序就是这样。 在这里,对于Segmentation故障信号,处理程序被多次调用,并且很明显MyfreeBuffers()给我释放已释放的内存的错误。我只想释放一

  • 我有一个便宜的5美元/月的服务器,1G内存为我的网站处理一些图像。在将GIF图像写入磁盘时,我很少会遇到PHP Imagick的分割错误。 我在console命令上设置了一个内存限制,希望PHP能够首先捕获这个问题,并抛出一个我可以正确处理的异常,但这不起作用。 特别的问题是某些GIF图像会导致它在这行代码中崩溃: 特定的GIF是与成人相关的GIF,因此我不确定是否可以共享它。 以下是我的服务器日

  • 分段错误发生在 运行Glewinfo 运行VisualInfo 测试程序(详细信息如下) 调用glGetProgramInterfaceiv(详细信息如下) 使用gdb实现glewinfo的堆栈跟踪 使用gdb实现visualinfo的堆栈跟踪 下面是使用已安装的GLEW库和glfw3(3.0.3)的测试程序 编译: 运行前。/basic I设置 (否则我会得到分段错误,因为它试图使用安装的GLE

  • 3.1 PG 无法达到 CLEAN 状态 创建一个新集群后,PG 的状态一直处于 active , active + remapped 或 active + degraded 状态, 而无法达到 active + clean 状态 ,那很可能是你的配置有问题。 你可能需要检查下集群中有关 Pool 、 PG 和 CRUSH 的配置项,做以适当的调整。 一般来说,你的集群中需要多于 1 个 OSD,

  • 进行 OSD 排障前,先检查一下 monitors 和网络。如果 ceph health 或 ceph -s 返回的是健康状态,这意味着 monitors 形成了法定人数。如果 monitor 还没达到法定人数、或者 monitor 状态错误,要先解决 monitor 的问题。核实下你的网络,确保它在正常运行,因为网络对 OSD 的运行和性能有显著影响。 2.1 收集 OSD 数据 开始 OSD

  • Monitor 维护着 Ceph 集群的信息,如果 Monitor 无法正常提供服务,那整个 Ceph 集群就不可访问。一般来说,在实际运行中,Ceph Monitor的个数是 2n + 1 ( n >= 0) 个,在线上至少3个,只要正常的节点数 >= n+1,Ceph 的 Paxos 算法就能保证系统的正常运行。所以,当 Monitor 出现故障的时候,不要惊慌,冷静下来,一步一步地处理。 1