Aleph-One-Marathon / alephone

Aleph One is the open source continuation of Bungie’s Marathon 2 game engine.
https://alephone.lhowon.org/
GNU General Public License v3.0
642 stars 101 forks source link

Feature request: Stacktraces in Lua errors #449

Open SolraBizna opened 9 months ago

SolraBizna commented 9 months ago

For simple scripts, line numbers are all that are needed (and a stacktrace would be noise). For complex scripts, stacktraces are sometimes necessary.

The Lua REPL performs all calls into Lua using this wrapper:

static int traceback (lua_State *L) {
  const char *msg = lua_tostring(L, 1);
  if (msg)
    luaL_traceback(L, L, msg, 1);
  else if (!lua_isnoneornil(L, 1)) {  /* is there an error object? */
    if (!luaL_callmeta(L, 1, "__tostring"))  /* try its 'tostring' metamethod */
      lua_pushliteral(L, "(no error message)");
  }
  return 1;
}

static int docall (lua_State *L, int narg, int nres) {
  int status;
  int base = lua_gettop(L) - narg;  /* function index */
  lua_pushcfunction(L, traceback);  /* push traceback function */
  lua_insert(L, base);  /* put it under chunk and args */
  globalL = L;  /* to be available to 'laction' */
  signal(SIGINT, laction);
  status = lua_pcall(L, narg, nres, base);
  signal(SIGINT, SIG_DFL);
  lua_remove(L, base);  /* remove traceback function */
  return status;
}

If we replace all calls in Aleph One Lua to lua_pcall with calls to a utility like that one, we will get stacktraces on all Lua errors. To reduce friction in the (common) case where stacktraces are unhelpful, the insertion of the traceback handler could be gated behind a preference checkbox, defaulting unchecked. (A command line argument would be a tougher sell, and requiring a special debug build is a can of worms we wouldn't want to open in my opinion.)

For extra ergonomics, I would make it so that only the first line of a Lua error is displayed on the screen, thus excluding the stacktrace from the inevitable error spam. The full stacktrace would still be written to the standard output. This could be gated by an additional preference or command line option if someone really wants to be able to spam tracebacks.

aaronfreed commented 9 months ago

I am naturally in full support of this idea, though I feel like the most sensible way to enable it is to simply have a Lua command that enables it, e.g.,

Game.lua_stack_traces = true

since, almost tautologically, a person that cares about debugging Lua either already writes Lua scripts themselves or will at least be communicating with such a person. If this is deemed insufficient for all possibilities, perhaps an additional command-line argument to enable this for all Lua scripts until the game quits would also make sense.