]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lua_error_p(): print whole stack trace
authorVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 30 Jan 2019 18:04:32 +0000 (19:04 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 11 Feb 2019 15:29:52 +0000 (16:29 +0100)
We use a function that's not in lua 5.1,
but it's been present in luajit since 2.0.0:
https://github.com/LuaJIT/LuaJIT/commit/fcddd5a3a

daemon/bindings/impl.c
daemon/bindings/impl.h

index 4bcc4315acbd2a41010df4711f61dd25f17017f6..b4671a07fa9b02fa404f277bc7cf8c3240c428ed 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <lua.h>
+#include <lauxlib.h>
 #include <string.h>
 
 /* Each of these just creates the correspondingly named lua table of functions. */
@@ -46,26 +47,21 @@ void kr_bindings_register(lua_State *L)
 
 void lua_error_p(lua_State *L, const char *fmt, ...)
 {
-       /* Push a string describing location in the "parent" lua function. */
-       lua_Debug d;
-       lua_getstack(L, 1, &d);
-       lua_getinfo(L, "Sln", &d);
-       if (strncmp(d.short_src, "[", 1) != 0) {
-               lua_pushstring(L, d.short_src);
-               lua_pushstring(L, ":");
-               lua_pushnumber(L, d.currentline);
-               lua_pushstring(L, ": error: ");
-               lua_concat(L, 4);
-       } else {
-               lua_pushstring(L, "error: ");
+       /* Push formatted custom message, prepended with "ERROR: ". */
+       lua_pushliteral(L, "ERROR: ");
+       {
+               va_list args;
+               va_start(args, fmt);
+               lua_pushvfstring(L, fmt, args);
+               va_end(args);
        }
-       /* Push formatted custom message. */
-       va_list args;
-       va_start(args, fmt);
-       lua_pushvfstring(L, fmt, args);
-       va_end(args);
-       /* Concatenate the two and throw a lua error. */
-       lua_concat(L,  2);
+       lua_concat(L, 2);
+       /* Add a stack trace and throw the result as a lua error. */
+       luaL_traceback(L, L, lua_tostring(L, -1), 0);
        lua_error(L);
+       /* TODO: we might construct a little more friendly trace by using luaL_where().
+        * In particular, in case the error happens in a function that was called
+        * directly from a config file (the most common case), there isn't much need
+        * to format the trace in this heavy way. */
 }
 
index a9dd3b52c130b3057d86f6e82c4fc438ff1259f1..d5dfff3148f6fd2c36ebcf5319bdcd075047972a 100644 (file)
 #define STR(s) STRINGIFY_TOKEN(s)
 #define STRINGIFY_TOKEN(s) #s
 
-/** @internal Annotate for static checkers. */
-KR_NORETURN int lua_error(lua_State *L);
-
-/** Throw a formatted lua error.  It doesn't return. */
+/** Throw a formatted lua error.
+ *
+ * The message will get prefixed by "ERROR: " and supplemented by stack trace.
+ * \return never!  It calls lua_error().
+ *
+ * Example:
+       ERROR: not a valid pin_sha256: 'a1Z/3ek=', raw length 5 instead of 32
+       stack traceback:
+               [C]: in function 'tls_client'
+               /PathToPREFIX/lib/kdns_modules/policy.lua:175: in function 'TLS_FORWARD'
+               /PathToConfig.lua:46: in main chunk
+ */
 KR_PRINTF(2) KR_NORETURN KR_COLD
 void lua_error_p(lua_State *L, const char *fmt, ...);
+/** @internal Annotate for static checkers. */
+KR_NORETURN int lua_error(lua_State *L);
 
 /** Shortcut for common case. */
 static inline void lua_error_maybe(lua_State *L, int err)