繁体   English   中英

libsigsegv并响应堆栈溢出

[英]libsigsegv and responding to a stack overflow

我们正在尝试测试学生代码,为了使流程自动化,我们想检测学生代码是否溢出了堆栈。

我使用libsigsegv库及其相应的stackoverflow_install_handler取得了一些成功。 它的运行非常出色,直到学生的代码两次将堆栈炸毁为止。

例如,这是一些示例输出:

[# ~]$ ledit ./interpreter
-> (use solution)
-> (fun 1 2)

*** Stack overflow detected ***
-> (fun 1 2)
Signal -10
[# ~]

初始的“ *检测到堆栈溢出* ”是理想的输出。 第二次刷新堆栈后,我得到的只是一个无用的“ Signal -10”,程序停止执行。 我想再次看到检测到堆栈溢出的消息,然后让代码继续执行。

在我的堆栈溢出处理程序中,我只是将溢出检测消息打印到stderr,并长时间跳回解释器中的“等待输入状态”。

谢谢你的帮助!

编辑

按照以下caf的建议,我们已经像下面这样添加了对sigsegv_leave_handler()的调用:

static void continuation(void *arg1, void *arg2, void *arg3) {                  
  (void)(arg1);                                                                 
  (void)(arg2);                                                                 
  (void)(arg3);                                                                 
  siglongjmp(errorjmp, 1);                                                      
}                                                                               

static void handler(int emergency, stackoverflow_context_t context) {           
 (void)emergency;                                                               
 (void)context;                                                                 
 fprintf(stderr, "\n*** Stack overflow detected ***\n");                        
 fflush(stderr);                                                                
 sigsegv_leave_handler(continuation, NULL, NULL, NULL);                         
}  

但是,输出仍然相同。

仅仅远离堆栈溢出并不一定足够。 我还没有看到要嵌入到其中的解释器的源代码,但是我的直觉是,堆栈溢出会导致某些内部解释器状态损坏,从而可能导致再次崩溃。 特别要注意的是,您得到的信号是SIGBUS(10),而不是SIGSEGV(11)。

想象一下以下情形:当解释器调用malloc时,堆栈溢出不足。 Malloc更改一些内部数据,然后调用辅助函数。 发生堆栈溢出,并且您将longjmp返回到解释器主循环。 您的malloc池现在已损坏,您无能为力。

我建议在检测到堆栈溢出时终止并重新启动解释器。 或者,准确找出解释器状态如何损坏,并安排它减少问题的发生(这可能很难!)。 您也可以在解释器中使用显式堆栈深度检查,而不是捕获SIGSEGV。 这样您就可以在SIGSEGV强制执行此问题之前安全地处理错误。

您是否遵循libsigsegv文档中的此警告?

...处理程序必须确保恢复正常的信号掩码(因为在执行处理程序时会阻塞许多信号),并且还必须调用sigsegv_leave_handler()来转移控制权; 那么只有它可以久远了。

尝试更紧密地遵循libsigsegv软件包中的示例代码tests / stackoverflow1.c support catching two consecutive stack overflows in a row. 此示例代码支持连续捕获两个连续的堆栈溢出。 特别是:

  • 在延续中使用longjmp而不是siglongjmp。
  • 在调用sigsegv_leave_handler之前先调用sigprocmask。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM