]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Merge pull request #8942 from Habbie/lua-backtrace
authorPeter van Dijk <peter.van.dijk@powerdns.com>
Thu, 24 Sep 2020 08:51:02 +0000 (10:51 +0200)
committerGitHub <noreply@github.com>
Thu, 24 Sep 2020 08:51:02 +0000 (10:51 +0200)
lua: add backtraces to errors

1  2 
ext/luawrapper/include/LuaContext.hpp

index ce0c37441d1f71d671342fd3c66eae3c59361819,5982757baf70d007276a9744ba3868eea56feee8..5017cd7b847b556cef0bdfab62a59f877b5be52d
@@@ -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<std::string>(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{};