libsigsegv和应对堆栈溢出 [英] libsigsegv and responding to a stack overflow

查看:1230
本文介绍了libsigsegv和应对堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正试图测试学生code,并在努​​力的过程自动化,我们想,如果一个学生的code溢出堆栈来检测。

We are attempting to test student code, and in an effort to automate the process, we'd like to detect if a student's code overflows the stack.

我见过用的libsigsegv库及其相应的stackoverflow_install_handler一些成功。它出色的作品,直到学生的code吹堆栈两次。

I've met with some success using the libsigsegv library and its corresponding stackoverflow_install_handler. It works brilliantly, until the student's code blows the stack twice.

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

For example, here's some sample output:

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

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

最初的检测到的 *堆栈溢出* 是所需要的输出。吹堆栈第二次之后,我得到的是一个无用的信号-10,程序停止执行。我想再次看到堆栈溢出检测到的消息,并让code继续执行。

The initial "* Stack overflow detected *" is the desirable output. After blowing the stack for the second time, all I get is an unhelpful "Signal -10" and the program stops execution. I'd like to see the stack overflow detected message again, and let the code continue execution.

在我的堆栈溢出的处理程序,我只是打印溢出检测信息到stderr和长期的跨preTER跳回到一个等待输入状态。

In my stack overflow handler, I'm just printing the overflow detection message to stderr and long jumping back to an "awaiting input state" in the interpreter.

感谢您的帮助!

修改

按下面的咖啡馆的建议下,我们增加了一个调用sigsegv_leave_handler()像这样:

As per caf's suggestion below, we've added a call to sigsegv_leave_handler() like so:

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);                         
}  

然而,输出仍是相同的。

However, the output is still the same.

推荐答案

简单longjmping从堆栈溢出客场未必足够。我还没有看到源$ C ​​$ C为国米preTER你嵌入到这一点,但我的直觉是,堆栈溢出留下一些内部间preTER状态破坏,可能会导致另一个崩溃。特别要注意的是你得到的信号是SIGBUS(10),而不是SIGSEGV(11)。

Simply longjmping away from a stack overflow isn't necessarily enough. I haven't seen the source code for the interpreter you're embedding this into, but my hunch is that the stack overflow leaves some internal interpreter state corrupted that may result in another crash. In particular, note that the signal you're getting is SIGBUS (10), not SIGSEGV (11).

想象以下情形:你只是短期堆栈溢出时间preTER电话的malloc 。 malloc的改变一些内部数据,然后调用一个辅助函数。堆栈溢出发生,你longjmp的回间preTER主循环。你的malloc池现已损坏,并没有什么可以做的。

Imagine the following scenario: You're just short of a stack overflow when the interpreter calls malloc. Malloc alters some internal data, then calls a helper function. A stack overflow occurs, and you longjmp back to the interpreter main loop. Your malloc pool is now corrupted, and there's nothing you can do about it.

我会建议终止,并在检测到堆栈溢出时重新启动跨preTER。另外,弄清楚究竟是如何相互preTER状态越来越损坏,并安排它要少的问题(这是十分困难!)。你也可以使用明确的堆栈深度检查,在国米preTER,而不是捕捉SIGSEGV;这将允许你在一个安全点处理错误,SIGSEGV强制发行前。

I would recommend terminating and restarting the interpreter when the stack overflow is detected. Alternately, figure out exactly how interpreter state is getting corrupted, and arrange for it to be less of a problem (this can be quite hard!). You could also use explicit stack depth checking in the interpreter rather than trapping SIGSEGV; this would allow you to handle the error at a safe point, before SIGSEGV forces the issue.

这篇关于libsigsegv和应对堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆