Lua会话具有受限的C/C++堆栈。

我需要在一个嵌入式多线程环境中安全地运行 Lua 会话,其中线程堆栈是预分配的并且具有固定的大小。 由于高的 C/C++ 栈消耗,允许出现脚本在 Lua 级别失败的情况。但不允许整个应用程序在 C/C++ 级别崩溃。我不能依赖 LUAI_MAXCCALLS 和 MAXCCALLS 提供的检查。如何正确检查和防止 Lua 会话的任何潜在栈溢出?什么是实施此类检查的正确位置?

点赞
用户6696291
用户6696291

你可以将需要调用的 C 函数包装在一个外层的 C 闭包中,以便检测你的 C/C++ 栈。该闭包将包含一个upvalue,参考实际需要调用的 C 函数:

CFunctionThunk(lua_state* l)
{
    检查可用的栈空间。
    如果(可用的栈空间 < 最小栈空间要求)
    {
        panic(...);
    }
    否则
    {
        actualFunction = 检索 upvalue;
        actualFunction(l);
    }
}

这将将所需的 thunk 栈空间添加到实际需要调用的函数的栈空间要求中,但这应该很小且常量。另外,在从一开始就调用 Lua 之前,您应该确保剩余的 C 栈空间至少足够容纳您的 Lua VM 和两个 C 函数堆栈帧(thunk + actual)。您可以在调试器中调查堆栈指针以查找所需的 thunk 和 Lua VM 空间的数量,这应该是(或多或少)常量。对于栈空间的检查也可以减少为在线程本地计数器中增加和减少,该计数器在 thunk 开始时增加,在其结束时减少。

另一种可能性是在函数调用时启用 Lua 调试挂钩,在那里检查 C 函数并在需要时进行 C 栈检查。但这可能会降低运行时性能,因为该挂钩也将对脚本中定义的 Lua 函数进行调用。

2016-08-11 16:27:10