如果我理解正确,默认情况下Lua会在发生错误时调用调试库“debug.traceback”。
然而,当将Lua嵌入到C代码中时,如下例所示: Simple Lua API Example
我们只在堆栈顶部提供错误消息。
即
if (status) {
/* If something went wrong, error message is at the top of */
/* the stack */
fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));
/* I want to print a stacktrace here. How do I do that? */
exit(1);
}
如何在初始错误后从C打印堆栈跟踪?
答案 0 :(得分:19)
默认情况下,Lua会在发生错误时调用调试库“debug.traceback”。
不,它不会。 Lua 运行时(lua.exe)会这样做,但Lua库本身不会这样做。如果你想要一个带有Lua错误的调用堆栈,那么你需要生成一个。
Lua运行时通过使用lua_pcall
's错误函数来完成此操作。调用错误函数时,堆栈尚未展开,因此您可以在那里获得堆栈跟踪。运行时使用的错误函数是这个:
static int traceback (lua_State *L) {
if (!lua_isstring(L, 1)) /* 'message' not a string? */
return 1; /* keep it intact */
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
return 1;
}
lua_getfield(L, -1, "traceback");
if (!lua_isfunction(L, -1)) {
lua_pop(L, 2);
return 1;
}
lua_pushvalue(L, 1); /* pass error message */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback */
return 1;
}
答案 1 :(得分:10)
在这里解决尼科尔的答案是一个有效的例子:
static int traceback(lua_State *L) {
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
lua_getfield(L, -1, "traceback");
lua_pushvalue(L, 1);
lua_pushinteger(L, 2);
lua_call(L, 2, 1);
fprintf(stderr, "%s\n", lua_tostring(L, -1));
return 1;
}
int main(int argc, char **argv) {
lua_State *L = lua_open();
luaL_openlibs(L);
lua_pushcfunction(L, traceback);
int rv = luaL_loadfile(L, "src/main.lua");
if (rv) {
fprintf(stderr, "%s\n", lua_tostring(L, -1));
return rv;
} else {
return lua_pcall(L, 0, 0, lua_gettop(L) - 1);
}
}
答案 2 :(得分:5)
我像你一样遇到了一些问题,我发现这种方式有效:
luaL_traceback(L, L, NULL, 1);
printf("%s\n", lua_tostring(L, -1));
由于luaL_traceback
正好debug.traceback()
用于打印堆栈,所以我认为这可能是一种正确的方法,您可以阅读有关luaL_traceback
的API手册或只是阅读来源Lua的代码来弄清楚params意味着什么。
答案 3 :(得分:2)
mxcl的代码存在一些问题:
static int traceback(lua_State *L) {
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
lua_getfield(L, -1, "traceback");
//---------------------------
lua_pop(L,-2); //to popup the 'debug'
//---------------------------
lua_pushvalue(L, 1);
lua_pushinteger(L, 2);
lua_call(L, 2, 1);
fprintf(stderr, "%s\n", lua_tostring(L, -1));
return 1;
}