【问题标题】:The lua stack overflow,is this a bug?lua堆栈溢出,这是一个错误吗?
【发布时间】:2010-05-10 00:01:52
【问题描述】:

几天前,我们的程序崩溃了。我在 lua 代码中发现了崩溃。所以我检查了lua代码,发现堆栈溢出。

请在函数luaD_precall中查看此代码:

1  if (!cl->isC) {  /* Lua function? prepare its call */
2       CallInfo *ci;
3       StkId st, base;
4       Proto *p = cl->p;
5       luaD_checkstack(L, p->maxstacksize);
6       func = restorestack(L, funcr);
7       if (!p->is_vararg) {  /* no varargs? */
8              base = func + 1;
9              if (L->top > base + p->numparams)
10             L->top = base + p->numparams;
11      }
12      else {  /* vararg function */
13             int nargs = cast_int(L->top - func) - 1;
14             base = adjust_varargs(L, p, nargs);
15             func = restorestack(L, funcr);  /* previous call may change the stack */
16      }
17      ci = inc_ci(L);  /* now `enter' new function */
18      ci->func = func;
19      L->base = ci->base = base;
20      ci->top = L->base + p->maxstacksize;
21      lua_assert(ci->top <= L->stack_last);
22      L->savedpc = p->code;  /* starting point */
23      ci->tailcalls = 0;
24      ci->nresults = nresults;
25      for (st = L->top; st < ci->top; st++)
26             setnilvalue(st);
27      L->top = ci->top;

在我的程序中,p-&gt;maxstacksize 在第 5 行之前为 79,当前堆栈大小为 51,调用 luaD_checkstack 后,堆栈大小增长到 130。

lua 函数使用 vararg,所以会运行到第 14 行。函数adjust_varargs 将被调用。

static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
        int i;
        int nfixargs = p->numparams;
       Table *htab = NULL;
       StkId base, fixed;
       for (; actual < nfixargs; ++actual)
           setnilvalue(L->top++);
#if defined(LUA_COMPAT_VARARG)
       if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
           int nvar = actual - nfixargs;  /* number of extra arguments */
           lua_assert(p->is_vararg & VARARG_HASARG);
           luaC_checkGC(L);
       htab = luaH_new(L, nvar, 1);  /* create `arg' table */

adjust_varargs()函数中,lua函数使用“arg”,所以luaC_checkGC会被调用。在luaC_checkGC 中,当前的 lua 堆栈大小将减少到 65! 调用栈是这样的:

luaC_step() 一小步() 传播标记() 遍历堆栈() 检查堆栈大小() luaD_reallocstack()

但是p-&gt;maxstacksize是79,stacksize不够…… 当程序运行到第27行时,L-&gt;top大于L-&gt;stack_last,在接下来的操作中会导致crash!

【问题讨论】:

  • 触发此崩溃的用户 C/Lua 代码是什么样的?
  • 如果您不发布您为创建此类场景而编写的代码,则无法判断您是否发现了错误。
  • 当 L->top 大于 L->stack_last 时,在我的脚本中,下一个操作 new 在堆栈上创建一个闭包,然后,堆栈增长,此操作会将旧堆栈复制到新栈,从 L->stack 到 L->stack_last,所以闭包不会被复制。现在闭包没有初始化。当调用闭包时,会发生非法内存访问,然后程序崩溃!

标签: lua stack overflow


【解决方案1】:

这是一个错误吗?

在我看来它像一个错误,但在这个级别上,我不是 Lua 内部的专家。不过,您似乎有一个非常连贯的解释,因此如果您还可以构建一个使错误可重现的简单应用程序,您应该将整个事情作为错误报告发送到lua@bazar2.conectiva.com.br

【讨论】:

猜你喜欢
  • 2013-06-16
  • 2011-02-08
  • 2023-03-04
  • 2019-12-17
  • 2014-01-26
  • 2019-02-16
  • 2011-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多