2010-05-07 1 views
0

Несколько дней назад наша программа вылетает. Я нашел краху в коде 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, в следующей операции, приведет к аварии !

+0

Что означает код пользователя C/Lua, чтобы вызвать этот сбой? – u0b34a0f6ae

+0

Невозможно определить, была ли найдена ошибка, если вы не опубликовали код, который вы написали, чтобы создать такой сценарий. – Puppy

+0

, когда верхняя часть L-> больше, чем L-> stack_last, в моем сценарии следующая операция - новое закрытие в стеке, затем стек растет, эта операция копирует старый стек в новый стек из L-> стек в L-> stack_last, поэтому закрытие не будет скопировано. Теперь закрытие не инициализировано. Когда будет вызвано замыкание, произойдет незаконный доступ к памяти , а затем сбой программы! – xiayong

ответ

0

Это ошибка?

Это выглядит как ошибка, но я не эксперт по внутренностям Lua на этом уровне. У вас, похоже, есть довольно последовательное объяснение, поэтому, если вы также можете создать простое приложение, которое сделает ошибку воспроизводимой, вы должны отправить все это как отчет об ошибке в [email protected].

+0

спасибо, я отправлю в команду lua – xiayong

+0

Лучше отправлять отчеты об ошибках в список Lua <[email protected]>; см .: http://lua-users.org/lists/lua-l/2010-04/msg00798.html –

+0

@ Doug: thanks; исправлено. –