【问题标题】:Handle segmentation fault multiple times in C++在 C++ 中多次处理分段错误
【发布时间】:2014-09-17 09:44:17
【问题描述】:

我能够处理一次分段错误。但是当它再次发生时,它会导致分段错误。是否可以多次处理 sigsegv 信号?

#define _POSIX_SOURCE
#include <signal.h>
#include <stdio.h>

int *a;

class FoobarException
{
  int thingy;
};

void signal_handler(int signum, siginfo_t *info, void *)
{
  printf("signal_handler\n");
  FoobarException *f = new FoobarException;
  throw f;
}

void call(int * c)
{
  struct sigaction act;
  act.sa_sigaction = signal_handler;
  sigemptyset (&act.sa_mask);
  act.sa_flags = SA_SIGINFO;
  sigaction (11, &act, NULL);

  try
    {
      printf("%d\n", *a);
    }
  catch (FoobarException *f)
    {
      printf("Hello!\n");
    }
}

int main()
{ 
  int *b;
  call(b);
  printf("I am here.\n");
  call(a);
}

第一个call(b) 处理段错误,但第二个call(a) 引发段错误。

【问题讨论】:

  • 您需要确保可以从分段错误中恢复。查看this问题了解更多详情。一般来说,为什么不调试到您没有根本没有分段错误的地步?
  • 我很确定 signal_handler 将从 c 代码中调用,因此您无法捕获您抛出的异常。捕捉在这里不起作用:ideone.com/4GiOiq。此外,即使你抓住了FoobarException,也会泄露它。
  • 您可能对 gcc -fnon-call-exceptions 功能感兴趣,否则抛出的异常只会终止信号处理程序并继续崩溃
  • 我认为try/catch 被指定用于捕获程序其他部分中抛出的异常作为软件设计的一部分,而不是处理硬件和软件陷阱。
  • 您是否有理由首先尝试处理多个段错误?我能想到的唯一原因是在退出之前生成自定义报告和/或“优雅地”处理它。 AFAIK,当发生段错误时,您的程序已经进入“不安全”状态(想想受了致命伤的动物)

标签: c++ segmentation-fault


【解决方案1】:

一旦出现分段错误,并且您处理了异常,但您并没有恢复原因。赌注是避免段错误。在您的示例程序中,您有指针,ab 但没有分配,所以,ab 包含垃圾(未分配),因此访问 *a 是有风险的,导致 seg 错误。

相反,为ab分配足够的空间,例如,

a = (int *) malloc(sizeof (int));

同样,对于b

完成后不要忘记释放,例如,

free(a);

【讨论】:

    【解决方案2】:

    您不能使用 C++ try/catch 块来处理 信号,因为 POSIX 信号 与 C++ 异常 不同。例如 signals 是异步的,由内核触发,而 C++ exceptions 是同步的:

    在编写处理函数时需要特别小心,因为 它们可以被异步调用。也就是说,可能会调用处理程序 在程序中的任何时候,都出乎意料。如果两个信号到达 在很短的时间间隔内,一个处理程序可以在另一个处理程序中运行。

    您可以找到here 更多关于如何编写正确的信号处理程序的信息。看看volatile sig_atomic_t

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      • 2018-10-08
      • 1970-01-01
      • 2013-10-28
      • 2014-04-10
      • 1970-01-01
      相关资源
      最近更新 更多