mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-11 17:51:04 +00:00
Push error handler afresh each time lua_pcall is used
Fixes "double fault" / "error in error handling" messages (issue #1423) and instead shows a complete backtrace.
This commit is contained in:
parent
8658c8d9b5
commit
3304e1e517
16 changed files with 188 additions and 92 deletions
|
@ -78,14 +78,14 @@ ScriptApiBase::ScriptApiBase()
|
|||
|
||||
luaL_openlibs(m_luastack);
|
||||
|
||||
// Add and save an error handler
|
||||
lua_pushcfunction(m_luastack, script_error_handler);
|
||||
m_errorhandler = lua_gettop(m_luastack);
|
||||
|
||||
// Make the ScriptApiBase* accessible to ModApiBase
|
||||
lua_pushlightuserdata(m_luastack, this);
|
||||
lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
|
||||
|
||||
// Add and save an error handler
|
||||
lua_pushcfunction(m_luastack, script_error_handler);
|
||||
lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER);
|
||||
|
||||
// If we are using LuaJIT add a C++ wrapper function to catch
|
||||
// exceptions thrown in Lua -> C++ calls
|
||||
#if USE_LUAJIT
|
||||
|
@ -133,13 +133,15 @@ bool ScriptApiBase::loadScript(const std::string &script_path, std::string *erro
|
|||
|
||||
lua_State *L = getStack();
|
||||
|
||||
int error_handler = PUSH_ERROR_HANDLER(L);
|
||||
|
||||
bool ok;
|
||||
if (m_secure) {
|
||||
ok = ScriptApiSecurity::safeLoadFile(L, script_path.c_str());
|
||||
} else {
|
||||
ok = !luaL_loadfile(L, script_path.c_str());
|
||||
}
|
||||
ok = ok && !lua_pcall(L, 0, 0, m_errorhandler);
|
||||
ok = ok && !lua_pcall(L, 0, 0, error_handler);
|
||||
if (!ok) {
|
||||
std::string error_msg = lua_tostring(L, -1);
|
||||
if (error)
|
||||
|
@ -150,9 +152,9 @@ bool ScriptApiBase::loadScript(const std::string &script_path, std::string *erro
|
|||
<< error_msg << std::endl << std::endl
|
||||
<< "======= END OF ERROR FROM LUA ========" << std::endl;
|
||||
lua_pop(L, 1); // Pop error message from stack
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
lua_pop(L, 1); // Pop error handler
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Push the list of callbacks (a lua table).
|
||||
|
@ -168,28 +170,28 @@ void ScriptApiBase::runCallbacksRaw(int nargs,
|
|||
FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments");
|
||||
|
||||
// Insert error handler
|
||||
lua_pushcfunction(L, script_error_handler);
|
||||
int errorhandler = lua_gettop(L) - nargs - 1;
|
||||
lua_insert(L, errorhandler);
|
||||
PUSH_ERROR_HANDLER(L);
|
||||
int error_handler = lua_gettop(L) - nargs - 1;
|
||||
lua_insert(L, error_handler);
|
||||
|
||||
// Insert run_callbacks between error handler and table
|
||||
lua_getglobal(L, "core");
|
||||
lua_getfield(L, -1, "run_callbacks");
|
||||
lua_remove(L, -2);
|
||||
lua_insert(L, errorhandler + 1);
|
||||
lua_insert(L, error_handler + 1);
|
||||
|
||||
// Insert mode after table
|
||||
lua_pushnumber(L, (int)mode);
|
||||
lua_insert(L, errorhandler + 3);
|
||||
lua_insert(L, error_handler + 3);
|
||||
|
||||
// Stack now looks like this:
|
||||
// ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n>
|
||||
|
||||
int result = lua_pcall(L, nargs + 2, 1, errorhandler);
|
||||
int result = lua_pcall(L, nargs + 2, 1, error_handler);
|
||||
if (result != 0)
|
||||
scriptError(result, fxn);
|
||||
|
||||
lua_remove(L, -2); // Remove error handler
|
||||
lua_remove(L, error_handler);
|
||||
}
|
||||
|
||||
void ScriptApiBase::realityCheck()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue