分段错误处理

2024-10-12 10:28:00
admin
原创
82
摘要:问题描述:我有一个应用程序,用于捕获任何分段错误或 ctrl-c。使用下面的代码,我能够捕获分段错误,但处理程序被一次又一次地调用。我该如何阻止它们。供您参考,我不想退出我的应用程序。我只需要小心地释放所有损坏的缓冲区。是否可以?void SignalInit(void ) { struct sigacti...

问题描述:

我有一个应用程序,用于捕获任何分段错误或 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);

}

处理程序如下。

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

这里对于分段错误信号,处理程序被多次调用,并且显然 MyfreeBuffers() 会给出释放已释放内存的错误。我只想释放一次,但仍然不想退出应用程序。

请帮忙。


解决方案 1:

此类事件的默认操作SIGSEGV是终止您的进程,但由于您已为其安装了处理程序,因此它将调用您的处理程序来覆盖默认行为。但问题是,在处理程序完成后,可能会重试分段错误指令,如果您未采取措施修复第一个分段错误,则重试的指令将再次出错,并不断重复。

因此,首先找出导致该问题的指令SIGSEGV并尝试修复它(您可以backtrace()在处理程序中调用类似的指令并亲自查看出了什么问题)

此外,POSIX 标准还规定,

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

因此,最理想的做法是首先修复段错误。段错误处理程序并非旨在绕过底层错误情况

因此,最好的建议是 -不要捕获SIGSEGV。让它转储核心。分析核心。修复无效的内存引用,然后就可以了!

解决方案 2:

我完全不同意“不要捕捉 SIGSEGV”的说法。

这是处理意外情况的非常好的做法。使用与 相关的信号机制来处理NULL指针(由 malloc 失败提供)setjmp/longjmp比在整个代码中分配错误情况管理要干净得多。

但请注意,如果您在上使用“sigaction” SEGV,则一定不要忘记说SA_NODEFER-sa_flags或者找到另一种方法来处理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
");

  return 0;
}

解决方案 3:

如果SIGSEGV再次触发,那么显而易见的结论是,对的调用MyfreeBuffers();没有解决根本问题(如果该函数确实只free()分配了一些内存,我不确定你为什么会认为它会这样做)。

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

解决方案 4:

您不应该在 之后尝试继续SIG_SEGV。这基本上意味着您的应用程序的环境在某种程度上被破坏了。可能是您刚刚取消引用了一个空指针,也可能是某个错误导致您的程序破坏了其堆栈、堆或某个指针变量,您只是不知道。唯一安全的做法是终止程序。

处理 control-C 是完全合法的。许多应用程序都这样做,但您必须非常小心在信号处理程序中执行的操作。您不能调用任何不可重入的函数。这意味着如果您MyFreeBuffers()调用 stdlib函数,您可能会陷入困境。如果用户在程序处于或free()中间时按下 control-C ,从而在操纵用于跟踪堆分配的数据结构的过程中途按下 或,则如果您在信号处理程序中调用或,则几乎肯定会破坏堆。malloc()`free()malloc()free()`

在信号处理程序中,唯一可以安全执行的操作就是设置一个标志,表示您捕获了信号。然后,您的应用可以定期轮询该标志,以决定是否需要执行某些操作。

解决方案 5:

好吧,您可以设置一个状态变量,并且只有在未设置时才释放内存。每次都会调用信号处理程序,据我所知您无法控制这一点。

解决方案 6:

我可以看到从 SIG_SEGV 中恢复的情况,如果您在循环中处理事件,并且其中一个事件导致分段违规,那么您只想跳过此事件,继续处理其余事件。在我看来,SIG_SEGV 类似于 Java 中的 NullPointerException。是的,在这两种情况之后,状态将不一致且未知,但是在某些情况下,您希望处理这种情况并继续。例如,在 Algo 交易中,您可以暂停订单的执行并允许交易者手动接管,而不会导致整个系统崩溃并破坏所有其他订单。

解决方案 7:

看起来至少在 Linux 下使用 -fnon-call-exceptions 选项的技巧可以解决问题。它将能够将信号转换为一般的 C++ 异常并以一般方式处理它。例如,查看linux3/gcc46:“-fnon-call-exceptions”,哪些信号是捕获指令?

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用