【问题标题】:Lua session with limited C/C++ stack具有有限 C/C++ 堆栈的 Lua 会话
【发布时间】:2015-08-06 17:47:04
【问题描述】:

我必须在嵌入式多线程环境中安全地运行 Lua 会话,其中线程堆栈是预先分配的且大小固定。

由于高 C/C++ 堆栈消耗,允许脚本在 Lua 级别失败。
它不允许整个应用程序在 C/C++ 级别崩溃。
我不能依赖 LUAI_MAXCCALLS 和 MAXCCALLS 提供的检查。

检查和防止 Lua 会话的任何潜在堆栈溢出的正确方法是什么?
实施此类检查的正确位置是什么?

【问题讨论】:

  • 不幸的是我不能。我有以字节为单位定义的堆栈大小,我无法更改它。并且没有从堆栈大小到 LUAI_MAXCCALLS 和 MAXCCALLS 的直接映射。
  • 不幸的是,当我处理 C/C++ 堆栈时,LUA_MINSTACK 控制着 Lua 堆栈。
  • 如果你在做一个没有 Lua 的纯 C/C++ 应用程序,你会遇到同样的问题,对吧?您想让其中一个线程在内存消耗的情况下安全崩溃,而其余线程继续。
  • 如果是这种情况,那么您需要找到一种方法来检测和处理来自 C/C++ 的堆栈溢出,而不是来自 Lua。让 Lua 在 Lua 中什么都不做就死掉,并使用您选择的 C/C++ 多线程库处理线程错误。
  • 嗯,Lua 栈在堆上,所以你只需要关心 C 栈。只有当 Lua 脚本调用 C 函数时,它才会增长。大概有一段常见的代码在 Lua 调用 C 之前总是被调用(源代码的快速 grep 建议在 ldo.c 中使用 luaD_precall),您可以在其中添加代码来检查 C 堆栈大小并抛出 Lua 错误以中止如果你越来越低,请编写脚本。

标签: multithreading lua


【解决方案1】:

您可以将要调用的 C 函数包装在外部 C 闭包中,以检查您的 C/C++ 堆栈。闭包将包含一个引用要调用的实际 C 函数的上值:

CFunctionThunk(lua_state* l)
{
    Check available stack space.
    if( available stack space < minimum stack space required )
    {
        panic(...);
    }
    else
    {
        actualFunction = retrieve upvalue;
        actualFunction(l);
    }
}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 2019-09-12
    • 2011-09-24
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多