2010-05-07 4 views
0

며칠 전에 프로그램이 중단되었습니다. 루아 코드에서 충돌을 발견했습니다. 그래서 루아 코드를 확인해 스택 오버 플로우를 발견했다.lua 스택 오버 플로우, 이것이 버그입니까?

기능 luaD_precall에서이 코드를보고하십시오 :의 p->maxstacksize 라인 5 전에 79 내 프로그램에서

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; 

, 현재 스택 크기 통화 luaD_checkstack 후, 51이며, 스택 크기는 130

로 성장

lua 함수는 vararg를 사용하므로 14 행까지 실행됩니다. 함수 adjust_varargs이 호출됩니다. 기능 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 */ 

는 루아 기능 사용 "인수는"그래서 luaC_checkGC가 호출됩니다. luaC_checkGC에서 현재 lua 스택 크기는 65로 줄어 듭니다! 이 같은 호출 스택 : 프로그램 실행 27 줄을 때

 
luaC_step() 
singlestep() 
propagatemark() 
traversestack() 
checkstacksizes() 
luaD_reallocstack() 

그러나 p->maxstacksize가 79이, 스택 크기가 ... 충분하지 않습니다는 L->top는 다음 작업에, 충돌의 원인이됩니다, L->stack_last보다 큰 !

+0

사용자 C/루아 코드를 보면이 충돌을 트리거하기 위해 무엇을 좋아 하는가? – u0b34a0f6ae

+0

그런 시나리오를 만들기 위해 작성한 코드를 게시하지 않으면 버그를 발견했는지 여부를 알 수 없습니다. L-가> 최고 L-보다 큰 경우 – Puppy

+0

는> stack_last 내 스크립트에서, 다음 작업 후, 스택의 성장,이 작업> L-에서, 새로운 스택 기존의 스택을 복사합니다 스택에 폐쇄를 새 스택을 L-> stack_last로 설정하면 클로저가 복사되지 않습니다. 이제 클로저가 초기화되지 않았습니다. 폐쇄가 호출되면 불법적 인 메모리 액세스가 발생하고 프로그램이 중단됩니다! – xiayong

답변

0

이 버그인가요?

버그처럼 보입니다.하지만이 레벨의 루아 내부에 대한 전문가는 아닙니다. 당신은 그래도 꽤 일관된 설명을 갖고있는 것 같다, 그래서 당신은 또한 버그를 재현 할 수있는 간단한 응용 프로그램을 구축 할 수 있다면, 당신은 [email protected]에 버그 리포트 전체를 보내야합니다.

+0

덕분에, 내가 루아 팀 그것은 루아 목록 <[email protected]>에 버그 리포트를 보내 더 나은 – xiayong

+0

에 게시 할 예정입니다; http://lua-users.org/lists/lua-l/2010-04/msg00798.html –

+0

@Doug : 감사합니다. 결정된. –