【问题标题】:I get a segmentation fault instead of an exception我得到分段错误而不是异常
【发布时间】:2013-01-31 17:25:28
【问题描述】:

在下面的代码中,在第一次迭代时出现异常,在第二次迭代中出现分段错误,没有打印任何错误消息。似乎没有捕获到异常:

int i = 0;
while(i++ < 10)
{
   try {
      cout << "Iteration: " << i << endl;
      // Code...
      cout << "OK" << endl;
   }
   catch(...)
   {
      cerr << "Error message" << endl;
      continue;
   }
}

Output:
Iteration 1
Error message
Iteration 2
Segmentation fault

这是正常的,还是真的有问题?

如果它应该是相关的,在那个代码块中我重置了一个 MySQL 连接,当我检查连接是否关闭时会生成异常。

谢谢。


平台:
Linux - OpenSuse 11.4
C++ - GCC 4.5.1
英特尔至强

【问题讨论】:

  • try-catch 无法捕获分段错误。您应该使用调试器来捕获它。
  • 我很确定它一定在您的// Code... 中。在您发布的内容中找不到段错误点...
  • 我设法通过编写 if (i==1) throw 0; else i = *(int*)0; 复制了您的输出,但这不是您的 // Code 所做的,是吗?

标签: c++ exception exception-handling segmentation-fault try-catch


【解决方案1】:

由于段错误不是(直接)由软件引起的,而是由处理器检测到您正在尝试访问无效内存(或以无效方式访问内存 - 例如写入受写保护的内存,执行内存这不应该被执行,等等),它不是“可捕获的”try/catch,它旨在捕获引发异常的软件。它们都被称为异常,但它们起源于系统软件/硬件的不同级别。

从技术上讲,您可以使用SIGSEGV 的信号处理程序来捕获段错误。但是,正如 Ivaylo 解释的那样,如果您遇到段错误,通常不允许“重试”。 SIGSEGV 的信号处理程序允许 longjmpexit,但不应只返回。

在此处阅读有关信号的更多信息: http://www.alexonlinux.com/signal-handling-in-linux

典型的C++异常(throw的结果)可以毫无问题地重试(当然,同样的异常当然可能再次抛出。

【讨论】:

    【解决方案2】:

    catch 子句捕获由throw 表达式引发的异常。在标准 C++(以及任何合理的 C++ 实现中)它们确实捕获操作系统或硬件检测到的错误。否则,编写异常安全代码会变得非常困难。

    【讨论】:

      【解决方案3】:

      你无法捕捉到这样的分段错误。此错误通常是不可恢复的,通常的 try-catch 不会处理此错误。这意味着发生了非常错误,可能是堆栈损坏或类似情况。尝试使用valgrind 检测导致分段错误的原因。

      【讨论】:

      • 在取消引用无效指针(null 或以其他方式指向未分配区域)时也会发生段错误,这是一个非常常见的错误,没有像堆栈损坏那样引人注目。
      猜你喜欢
      • 1970-01-01
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      • 2018-07-01
      • 2016-06-24
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多