Lua设置了默认错误处理程序

时间:2015-05-04 02:49:29

标签: c exception error-handling lua

默认的lua_pcall错误处理程序(从Lua 5.3开始)不执行任何操作,让异常消息保留在堆栈顶部。我们想要更改此内容,以便除luaL_traceback失败时堆栈顶部的异常消息外,我们还会获得lua_pcall回溯。

不幸的是,我认为这意味着我们需要在所有的pcalls下面插入错误处理程序。最强有力的方式似乎是这样的:

/* push function and arguments */
lua_pushstuff...

/* push error handler */
lua_pushcfunction(L, my_error_handler);

/* move the error handler just below the function and arguments */
lua_insert(L, -(number of args + 1));

if (lua_pcall(L, nargs, nresults, -(number of args + 1))) {
    /* error here (my_error_handler was invoked) */
    /* do something with lua_tostring(L, -1) */
}

/* afterwards, pop the error handler (it may be below return values) */
lua_pop(L, 1);

但是这会在每个pcall引入噪声(我们有很多,因为我们有一些从C异步调用的Lua回调)并且感觉有点重复。我认为这可以包含在一些lua_mypcall函数中,该函数可以自动执行此设置,但我有两个问题:

  1. 这种方法是否会在pcall之前(或内部)更复杂的堆栈操作中断? (我还不是很熟悉Lua堆栈)

  2. 因为我们想要对大多数pcalls进行回溯,所以将这个错误处理程序设置为默认值是有意义的,并且手动指定前面的错误处理程序(什么都不做),所以有没有办法全局更改Lua状态的默认错误处理程序?

  3. 我看到lua_pcallk有一些代码errfunc == 0,但它似乎不可配置。我们可以破解Lua实现来手动更改默认值,但是想避免这种情况。

    我们正在使用Lua 5.3。感谢。

1 个答案:

答案 0 :(得分:3)

您的基本方法是合理的,但您错过了lua_remove(而不是lua_pop)并且您的堆栈索引错误。试试这个:

int lua_mypcall( lua_State* L, int nargs, int nret ) {
  /* calculate stack position for message handler */
  int hpos = lua_gettop( L ) - nargs;
  int ret = 0;
  /* push custom error message handler */
  lua_pushcfunction( L, my_error_handler );
  /* move it before function and arguments */
  lua_insert( L, hpos );
  /* call lua_pcall function with custom handler */
  ret = lua_pcall( L, nargs, nret, hpos );
  /* remove custom error message handler from stack */
  lua_remove( L, hpos );
  /* pass return value of lua_pcall */
  return ret;
}