3
votes

In a game that uses Lua for extensibility, when an error is thrown in a script, I'd like to show the user an error log, i.e. an error message and a stack trace, somewhat like this:

if (lua_pcall(L, nargs, nresults, 0) != 0) log.printline(lua_tostring(L, -1));

This only prints the error message, though, not the call stack.

I am aware I could use debug.traceback, i.e. grabbing the function from the debug table through the API and then calling it, but I don't want to load the debug table at all because of security concerns, i.e. allowing a malicious user to write scripts that screw with the system and other global tables. (For the same reason I don't load io and instead expose my own functions.)

I'm not using a bridge of any sort, I use the Lua API directly, through P/Invoke.

How would I go about printing a stack trace following a failed lua_pcall call, without having to expose the debug table to the end user?

2
You could always sandbox Lua, because I do not believe there's any other way. - warspyking
Unless xpcall would help (?) I haven't messed with it much - warspyking
You don't have to load the entire debug library just to get access to debug.traceback. - Nicol Bolas

2 Answers

3
votes

Call luaL_traceback:

void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level);

Creates and pushes a traceback of the stack L1. If msg is not NULL it is appended at the beginning of the traceback. The level parameter tells at which level to start the traceback.

You probably want to use L1=L. See the source of lua.c for an example of use.

0
votes

4th argument in lua_pcall is error handler. So you can call some think like debug.traceback in this function to get stacktrace and do log in this function.