From: Peter van Dijk Date: Thu, 24 Sep 2020 08:51:02 +0000 (+0200) Subject: Merge pull request #8942 from Habbie/lua-backtrace X-Git-Tag: auth-4.4.0-alpha1~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5c5ee9e6ffccdd58080165b94630981afed3d57f;p=thirdparty%2Fpdns.git Merge pull request #8942 from Habbie/lua-backtrace lua: add backtraces to errors --- 5c5ee9e6ffccdd58080165b94630981afed3d57f diff --cc ext/luawrapper/include/LuaContext.hpp index ce0c37441d,5982757baf..5017cd7b84 --- a/ext/luawrapper/include/LuaContext.hpp +++ b/ext/luawrapper/include/LuaContext.hpp @@@ -1419,15 -1433,33 +1433,33 @@@ private // this function just calls lua_pcall and checks for errors static PushedObject callRaw(lua_State* state, PushedObject functionAndArguments, const int outArguments) { + // provide traceback handler + int tbindex = lua_gettop(state) - (functionAndArguments.getNum() - 1); + lua_pushcfunction(state, gettraceback); + + // move it back up, before our function and arguments + lua_insert(state, tbindex); + // calling pcall automatically pops the parameters and pushes output - const auto pcallReturnValue = lua_pcall(state, functionAndArguments.getNum() - 1, outArguments, 0); + const auto pcallReturnValue = lua_pcall(state, functionAndArguments.getNum() - 1, outArguments, tbindex); functionAndArguments.release(); + lua_remove(state, tbindex); // remove traceback function + + // if pcall failed, analyzing the problem and throwing if (pcallReturnValue != 0) { + + // stack top: {error, traceback} + lua_rawgeti(state, -1, 1); // stack top: {error, traceback}, error + lua_rawgeti(state, -2, 2); // stack top: {error, traceback}, error, traceback + lua_remove(state, -3); // stack top: error, traceback + + PushedObject traceBackRef{state, 1}; + const auto traceBack = readTopAndPop(state, std::move(traceBackRef)); // stack top: error PushedObject errorCode{state, 1}; - // an error occured during execution, either an error message or a std::exception_ptr was pushed on the stack + // an error occurred during execution, either an error message or a std::exception_ptr was pushed on the stack if (pcallReturnValue == LUA_ERRMEM) { throw std::bad_alloc{};