Lua5.2でluaの函数内にてエラった時にtracebackを取得するには
Luaを自分のプログラムに組み込んでなんやらしている時に、
local function g() prin("hoge") -- 本当はprint("hoge")と書きたかった. end local function f() g() end f()
というコードがあるとして、これを実行するために、
int error_code = lua_pcall(L, nargs, nresults, 0); if (error_code) { luaL_traceback(L, L, lua_tostring(L, 1), 1); std::cout << lua_tostring(L, 1) << std::endl; }
なんて事をしても、lua_pcall()終了時点でstackは空になっているためtraceback自体表示されない. 正しくは、
namespace { int traceback(lua_State* L) { const char* message(lua_tostring(L, 1)); if (message) { luaL_traceback(L, L, message, 1); } else if (!lua_isnoneornil(L, 1)) { if (!luaL_callmeta(L, 1, "__tostring")) { lua_pushliteral(L, "(no error message)"); } } return 1; } } ... int error_func = lua_gettop(L) - nargs; // 呼び出した函数のstack数で引く lua_pushcfunction(L, traceback); // traceback函数をpush lua_insert(L, error_func); error_code = lua_pcall(L, nargs, nresults, error_func); //traceback函数のhandle(index)を指定 lua_remove(L, error_func); if (error_code) { const char* error_message(lua_tostring(L, 1)); std::cout << "luaL_pcall:"; std::cout << error_message << std::endl; lua_close(L); return 1; } ...
これで、
luaL_pcall:[string "?"]:3: attempt to call global 'prin' (a nil value) stack traceback: [string "?"]:3: in function 'g' [string "?"]:7: in function 'f' [string "?"]:10: in main chunk
というようにちゃんとstack tracebackが表示される.