2

我正在为我们的产品实现跨平台脚本语言。需要检测并正确处理语言 VM 中的堆栈溢出情况。在你跳进去说首先确保没有堆栈溢出之前,请重新阅读我的第一句话 - 这是一种脚本语言,最终用户可能会用这种语言编写不正确的程序,这可能会导致堆栈溢出,例如无尽递归。

现在我知道如何在 Windows 中检测堆栈溢出并从中恢复(参见http://support.microsoft.com/kb/315937)。但是我无法为 Mac OS X 找到任何解决方案。

VM 使用 C++ 实现:Windows 上的 MSVC++,Mac OS X 上的 GCC。

理想情况下,该机制必须基于 UNIX 功能,因为我们还计划移植到 Linux。

谢谢。

4

3 回答 3

3

OCaml 具有与您相同的约束(程序员可能导致堆栈溢出的“脚本”语言)。它的本机编译器使用系统堆栈进行函数调用——正如你所做的那样——它处理堆栈溢出(将它们具体化为异常)。

如果您没有收到更明确的答案,我建议您在OCaml 源代码中查看它是如何完成的。

~/ppc $ cat >> t.ml

let rec f x = (f x) + (f x) ;;

f 0 ;;

~/ppc $ ocamlopt t.ml
~/ppc $ ./a.out 
Fatal error: exception Stack_overflow

以上是在 Mac OS X Leopard 上。#ifdef HAS_STACK_OVERFLOW_DETECTION在源文件中搜索。

于 2009-11-19T13:07:04.487 回答
0

您不能确定程序的最大堆栈大小、堆栈的开头然后计算堆栈地址的结尾吗?在 vm 中的每个操作之前,您可以检查堆栈是否会溢出(增加超过最大地址)然后引发异常。另一种方法是在堆栈结束后写入一个标识符(如 DEADBEEF 左右),并在每次堆栈操作后检查它的值。


我仍然不明白为什么您无法添加检查(这是通常检测堆栈操作的方式)。但是您仍然可以在堆栈区域的末尾添加一个硬件断点(写入时)。当它中断时,你知道你有一个stackoverflow。我不会建议它,因为它可能会破坏您的调试环境。

但基本上 - 如果你有一个虚拟机,你也有读取代码(例如字节码)并编译/解释它的地方。那是您可以检查标记的地方(类似于检测堆栈缓冲区溢出的检查)。

于 2009-11-19T13:15:19.793 回答
0

看看libsigsegv。它是一个带有例程的 C 库,可帮助您实现堆栈溢出处理程序等。

于 2009-11-20T06:08:13.680 回答