Lua バグ

5.0

これはバージョン5.0のLuaに含まれるすべての既知のバグリストの日本語訳である。 原文 も参照のこと。

Lua 5.0

  1. lua_closethread が存在しない。
    報告者 Nguyen Binh 2003/04/28 5.0.2で修正済み。

    パッチ: マニュアルの間違い。スレッドはガベージコレクションの対象である。

  2. 走行中のコルーチンをresumeするとLuaがクラッシュする。
    報告者 Alex Bilyk 2003/05/09 5.0.2で修正済み。

    例:
    function co_func (current_co)
       coroutine.resume(co)
    end
    co = coroutine.create(co_func)
    coroutine.resume(co)
    coroutine.resume(co)     --> seg. fault
    
    パッチ:
    * ldo.c:
    325,326c325
    <     if (nargs >= L->top - L->base)
    <       luaG_runerror(L, "cannot resume dead coroutine");
    ---
    >     lua_assert(nargs < L->top - L->base);
    329c328,329
    <   else if (ci->state & CI_YIELD) {  /* inside a yield? */
    ---
    >   else {  /* inside a yield */
    >     lua_assert(ci->state & CI_YIELD);
    344,345d343
    <   else
    <     luaG_runerror(L, "cannot resume non-suspended coroutine");
    351a350,358
    > static int resume_error (lua_State *L, const char *msg) {
    >   L->top = L->ci->base;
    >   setsvalue2s(L->top, luaS_new(L, msg));
    >   incr_top(L);
    >   lua_unlock(L);
    >   return LUA_ERRRUN;
    > }
    >
    >
    355a363,368
    >   if (L->ci == L->base_ci) {
    >     if (nargs >= L->top - L->base)
    >       return resume_error(L, "cannot resume dead coroutine");
    >   }
    >   else if (!(L->ci->state & CI_YIELD))  /* not inside a yield? */
    >     return resume_error(L, "cannot resume non-suspended coroutine");
    

  3. file:close をファイルなしで呼び出してはいけない (seg fault を起こす)。
    報告者 Tuomo Valkonen 2003/05/27 5.0.2で修正済み。

    例:
    > io.stdin.close()    -- 正しい呼び出しは io.stdin:close()
    
    パッチ:
    * liolib.c:
    161c161
    <   if (lua_isnone(L, 1)) {
    ---
    >   if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) {
    

  4. Cの関数が現在のスタックトップよりも大きなスタックを使える。
    報告者 Alex Bilyk 2003/06/09 5.0.2で修正済み。

    例:
    lua.c を変更して lua_assert を定義し、Luaを再コンパイルする必要がある。
    * lua.c:
    381a382
    >   lua_checkstack(l, 1000);
    
    パッチ:
    * lgc.c:
    247c247
    <     if (!(ci->state & CI_C) && lim < ci->top)
    ---
    >     if (lim < ci->top)
    

  5. コルーチンが中断したときにpcのアドレスが無効になる。
    報告者 Nick Trout 2003/07/07 5.0.2で修正済み。

    例:
    function g(x)
        coroutine.yield(x)
    end
    
    function f (i)
      debug.sethook(print, "l")
      for j=1,1000 do
        g(i+j)
      end
    end
    
    co = coroutine.wrap(f)
    co(10)
    pcall(co)
    pcall(co)
    
    パッチ:
    * lvm.c:
    402d401
    <   L->ci->u.l.pc = &pc;
    405a405
    >   L->ci->u.l.pc = &pc;
    676,678c676
    <           lua_assert(ci->u.l.pc == &pc &&
    <                      ttisfunction(ci->base - 1) &&
    <                      (ci->state & CI_SAVEDPC));
    ---
    >           lua_assert(ttisfunction(ci->base - 1) && (ci->state & CI_SAVEDPC));
    

  6. 回収されたユーザーデータが新しいGCの閾値にカウントされ、メモリ消費が増える。
    報告者 Roberto 2003/07/25 5.0.2で修正済み。

    例:
    a = newproxy(true)
    getmetatable(a).__gc = function () end
    for i=1,10000000 do
      newproxy(a)
      if math.mod(i, 10000) == 0 then print(gcinfo()) end
    end
    
    パッチ:
    * lgc.h:
    18c18
    < void luaC_separateudata (lua_State *L);
    ---
    > size_t luaC_separateudata (lua_State *L);
    
    * lgc.c:
    113c113,114
    < void luaC_separateudata (lua_State *L) {
    ---
    > size_t luaC_separateudata (lua_State *L) {
    >   size_t deadmem = 0;
    127a129
    >       deadmem += sizeudata(gcotou(curr)->uv.len);
    136a139
    >   return deadmem;
    390c393
    < static void checkSizes (lua_State *L) {
    ---
    > static void checkSizes (lua_State *L, size_t deadmem) {
    400c403
    <   G(L)->GCthreshold = 2*G(L)->nblocks;  /* new threshold */
    ---
    >   G(L)->GCthreshold = 2*G(L)->nblocks - deadmem;  /* new threshold */
    454c457,458
    < static void mark (lua_State *L) {
    ---
    > static size_t mark (lua_State *L) {
    >   size_t deadmem;
    467c471
    <   luaC_separateudata(L);  /* separate userdata to be preserved */
    ---
    >   deadmem = luaC_separateudata(L);  /* separate userdata to be preserved */
    475a480
    >   return deadmem;
    480c485
    <   mark(L);
    ---
    >   size_t deadmem = mark(L);
    482c487
    <   checkSizes(L);
    ---
    >   checkSizes(L, deadmem);
    

  7. IBM AS400 (OS400) は sizeof(void *)==16 であり、 `printf' の `%p' が60文字ものテキストを生成するため、 `tostring' がバッファオーバーフローする。
    報告者 David Burgess 2003/08/25 5.0.2で修正済み。

    例:
    print{};  -- (AS400 マシンで)
    パッチ:
    * liolib.c:
    178c178
    <   char buff[32];
    ---
    >   char buff[128];
    
    * lbaselib.c:
    327c327
    <   char buff[64];
    ---
    >   char buff[128];
    

  8. 構文 `local function' でスタックサイズを増やしていなかった。
    報告者 Rici Lake 2003/09/26 5.0.2で修正済み。

    例:
    -- コンパイル済みコードでこれを実行する必要がある
    local a,b,c
    local function d () end
    
    パッチ:
    * lparser.c:
    1143a1144
    >   FuncState *fs = ls->fs;
    1145c1146,1147
    <   init_exp(&v, VLOCAL, ls->fs->freereg++);
    ---
    >   init_exp(&v, VLOCAL, fs->freereg);
    >   luaK_reserveregs(fs, 1);
    1148c1150,1152
    <   luaK_storevar(ls->fs, &v, &b);
    ---
    >   luaK_storevar(fs, &v, &b);
    >   /* debug information will only see the variable after this point! */
    >   getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
    

  9. countフックが設定されていなくても呼び出される。
    報告者 Andreas Stenius 2003/10/06 5.0.2で修正済み。

    例:
    以下のようにフックを設定してみよ。
    
      lua_sethook(L, my_hook, LUA_MASKLINE | LUA_MASKRET, 1);
    
    (奇妙にもcountフックを設定せずにcountを1としているが、間違いではない)
    
    パッチ:
    * lvm.c:
    69c69
    <   if (mask > LUA_MASKLINE) {  /* instruction-hook set? */
    ---
    >   if (mask & LUA_MASKCOUNT) {  /* instruction-hook set? */
    


最終更新: Thu Mar 18 08:20:09 BRT 2004