【问题标题】:handle SIGSEGV in Linux?在 Linux 中处理 SIGSEGV?
【发布时间】:2010-06-10 06:48:04
【问题描述】:

我需要在我的 Linux 应用程序中处理 SIGSEGV。原因是在生成核心转储之前必须进行一些清理(3 方库)。更重要的是,清理必须在调用线程的上下文中执行,不能在信号处理程序中执行。 所以我计划在信号处理程序中将控制权传递给调用线程,在清理完成后,然后使用 raise(SIGSEGV) 生成核心转储。

真正的问题似乎是 signal_handler 无法将控制权传递给调用线程,无论我使用 post_sem 还是其他一些。 有处理这个案子的想法吗?是否可以劫持 SIGSEGV,然后在 SIGSEGV 处理程序中返回另一个线程进行一些清理?

信号(SIGSEGV,信号处理程序);

signal_handler() { ... post_sem(); ... }

调用线程() { wait_sem(); 清理(​​); ... }

【问题讨论】:

  • 您描述的方法实际上是最接近有效的方法。标准要求sem_post(POSIX 版本)是异步信号安全的。

标签: linux handler signals segmentation-fault


【解决方案1】:

您想在 SIGSEGV 之后进行清理(即严重错误)...我觉得这有点奇怪,因为 1)如果您正在调试应用程序,您应该将所有内容原封不动地存储在核心文件中,以便您可以准确确定发生了什么,2)如果你有一个客户的发布应用程序(比如说)......它不应该是 SIGSEGV :) (反正不是我的问题,只是说......)

关于主题,

我认为您可以尝试在所有线程中阻止 SIGSEGV,但您尝试进行清理的线程除外;这应该使操作系统将信号传递给该特定线程。我能想到的其他解决方案类似于 setjmp() / longjmp() (虽然还没有测试过这些)。

请注意,一旦您的程序获得了 SEGV,您就处于不稳定的状态(即您的清理也可能失败并生成另一个 SEGV 等),因此您应该考虑只使用内核崩溃。

【讨论】:

  • 无济于事。 SIGSEGV 被传递给导致无效访问的特定线程,而不是整个进程。
【解决方案2】:

在遇到 SIGSEGV 后,可靠运行任何代码是不可能的。有时你可能会侥幸逃脱,但你不能相信你的程序以后会按预期工作。例如,如果您因为堆损坏而拥有一个 SIGSEGV,那么如果您的 3rd 方库正在清理任何内存,您就会遇到问题。

为了获得可靠的解决方案,我会考虑您是否真的需要运行该清理代码,或者是否有其他方法来处理这种情况(在下次启动时检查是否有不正常的关闭,...)。

【讨论】:

    【解决方案3】:

    我认为你不应该尝试运行任何清理内存状态的东西,尤其是将其写入磁盘,如果成功,你会导致数据损坏。

    如果可能的话,记录一些状态信息可能有助于调试,但你不应该依赖于能力。

    相反,程序应该在记录状态信息后返回默认处理程序(和转储核心等),或者调用 _exit 并退出而不进行任何清理。

    如果您需要在崩溃后重新启动清理工作,请改为在下次启动时进行。

    【讨论】:

      猜你喜欢
      • 2018-07-26
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      • 2018-11-12
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多