libsigsegv并响应堆栈溢出

Bur*_*hi5 5 c stack-overflow signals segmentation-fault

我们正在尝试测试学生代码,并且为了自动化该过程,我们想要检测学生的代码是否溢出堆栈.

我使用libsigsegv库及其相应的stackoverflow_install_handler获得了一些成功.它的工作非常出色,直到学生的代码将堆栈吹两次.

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

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

*** Stack overflow detected ***
-> (fun 1 2)
Signal -10
[# ~]
Run Code Online (Sandbox Code Playgroud)

初始" *检测到堆栈溢出* "是理想的输出.在第二次吹掉堆栈之后,我得到的只是一个无用的"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);                         
}  
Run Code Online (Sandbox Code Playgroud)

但是,输出仍然相同.

bdo*_*lan 3

仅仅通过 longjmping 避免堆栈溢出不一定是足够的。我还没有看到您将其嵌入到的解释器的源代码,但我的预感是堆栈溢出导致一些内部解释器状态损坏,可能导致另一次崩溃。特别要注意的是,您收到的信号是 SIGBUS (10),而不是 SIGSEGV (11)。

\n\n

想象一下以下场景:当解释器调用\xe3\x80\x80 时,你只是缺少堆栈溢出malloc。Malloc 更改一些内部数据,然后调用辅助函数。发生堆栈溢出,并且您 longjmp 返回解释器主循环。您的 malloc 池现在已损坏,您对此无能为力。

\n\n

我建议在检测到堆栈溢出时终止并重新启动解释器。或者,准确地弄清楚解释器状态是如何被损坏的,并安排它不再是一个问题(这可能非常困难!)。您还可以在解释器中使用显式堆栈深度检查,而不是捕获 SIGSEGV;这将允许您在 SIGSEGV 强制问题之前在安全点处理错误。

\n