分段错误处理

2024-10-12 10:28:00
admin
原创
252
摘要:问题描述:我有一个应用程序,用于捕获任何分段错误或 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”,哪些信号是捕获指令?

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2577  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1553  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   26  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   21  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   18  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用