【问题标题】:Multiple lua_calls exiting and generating a "C stack overflow"多个 lua_call 退出并生成“C 堆栈溢出”
【发布时间】:2016-07-12 10:54:49
【问题描述】:

我正在使用带有一些 Lua 绑定的 C++ 的多进程环境中工作,使用 Lua 函数来管理进程的某些方面,其中有一个共享的 Lua 上下文。

我使用的一般形式是挂钩某些事件,触发 Lua 函数,这些函数依次到达 C++ 代码。

我将两个与进程相关的参数压入栈中,然后发出

lua_call(L, 2, 0);

问题是某些特定的lua_call 达到了终止功能(预期行为),但是由于lua_call 没有返回,因此堆栈没有被释放。在大约 200 次这样的调用之后,由于 C 堆栈溢出,Lua 出现恐慌。

我已经在每个钩子上打印了 Lua 堆栈,我可以看到它在增长。我试过使用lua_pop(L, 2)(堆栈每次增长2),lua_settop(L, 0)在Lua使用参数并发出回调之后,就在终止进程之前,但无济于事。

我不能调用lua_close(L),因为这会破坏进程之间共享的上下文,并会导致其他进程访问 NULL 上下文。

【问题讨论】:

  • 我认为最简单的解决方案是不在进程之间共享您的 Lua 上下文。 (实际上,我很惊讶它有效)
  • 你需要使用某种锁,如果你同时通过一个 lua VM 运行两个线程,那么你会得到未定义的行为。
  • 为什么 lua 调用不返回?如果这样做,您将泄漏堆栈条目,这与规范一致。当你用一些参数调用“lua_call”时,函数调用下面的参数将受到lua的保护,它会虚拟地移动堆栈帧以支持调用。 “原始”堆栈仅在您从函数返回时才可访问。您最终必须从通话中返回,否则这些条目将永远泄露 AFAIK。
  • @ChrisBeck:感谢您富有洞察力的评论!据我了解,在任何给定点,即使我可以查看任何堆栈帧,我也只能释放当前的堆栈帧。调用不返回的原因是因为调用的进程已因调用而被终止(同样,这是所需的行为)。我可以尝试的另一个选择是在调用以某种方式返回后安排进程终止。
  • @vladimird:您可以为每个进程使用单独的 Lua 线程。它们有独立的堆栈,当您不再需要它们时会进行垃圾回收。

标签: c++ lua


【解决方案1】:

我的解决方法不是直接终止发出lua_call 的进程,而是设置一个标志并仅在调用返回后终止它,确保没有剩余的堆栈帧。

再次感谢 Chris Beck 对 Lua 堆栈工作原理的深刻评论。

【讨论】:

    猜你喜欢
    • 2012-12-20
    • 2011-03-02
    • 2014-01-17
    • 1970-01-01
    • 2015-09-08
    • 2019-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多