Несколько дней назад наша программа вылетает. Я нашел краху в коде lua. Поэтому я проверяю код 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->maxstacksize
составляет 79 перед строкой 5, ток STACKSIZE составляет 51, после вызова luaD_checkstack
, то STACKSIZE вырастет до 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 «аргумент», так luaC_checkGC
будет называться. В luaC_checkGC
текущий размер стека lua будет уменьшен до 65! Стек вызовов, как это:
luaC_step() singlestep() propagatemark() traversestack() checkstacksizes() luaD_reallocstack()
Но p->maxstacksize
79, то STACKSIZE не хватает ... Когда программа запуска на линию 27, то L->top
больше, чем L->stack_last
, в следующей операции, приведет к аварии !
Что означает код пользователя C/Lua, чтобы вызвать этот сбой? – u0b34a0f6ae
Невозможно определить, была ли найдена ошибка, если вы не опубликовали код, который вы написали, чтобы создать такой сценарий. – Puppy
, когда верхняя часть L-> больше, чем L-> stack_last, в моем сценарии следующая операция - новое закрытие в стеке, затем стек растет, эта операция копирует старый стек в новый стек из L-> стек в L-> stack_last, поэтому закрытие не будет скопировано. Теперь закрытие не инициализировано. Когда будет вызвано замыкание, произойдет незаконный доступ к памяти , а затем сбой программы! – xiayong