diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-09-14 21:37:34 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-09-14 21:37:34 +0100 |
commit | 92a1256394cde1ae5210fbfdcef78159b73b3ac2 (patch) | |
tree | f7efb17d5833b85766ea772c9a2ba2848f005bc8 /src | |
parent | 03b7a344fd6ab43449763f6c75cafffb1228fe65 (diff) | |
download | rspamd-92a1256394cde1ae5210fbfdcef78159b73b3ac2.tar.gz rspamd-92a1256394cde1ae5210fbfdcef78159b73b3ac2.zip |
Print stack trace on lua errors.
Diffstat (limited to 'src')
-rw-r--r-- | src/lua/lua_common.c | 52 | ||||
-rw-r--r-- | src/lua/lua_common.h | 1 | ||||
-rw-r--r-- | src/lua/lua_config.c | 86 |
3 files changed, 91 insertions, 48 deletions
diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index 2c8403e96..3841ffe14 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -291,6 +291,8 @@ rspamd_init_lua_filters (struct rspamd_config *cfg) GList *cur; struct script_module *module; lua_State *L = cfg->lua_state; + GString *tb; + gint err_idx; rspamd_lua_set_path (L, cfg); cur = g_list_first (cfg->script_modules); @@ -303,10 +305,17 @@ rspamd_init_lua_filters (struct rspamd_config *cfg) continue; } + tb = g_string_new (""); + lua_pushlightuserdata (L, tb); + lua_pushcclosure (L, &rspamd_lua_traceback, 1); + err_idx = lua_gettop (L); + if (luaL_loadfile (L, module->path) != 0) { - msg_info_config ("load of %s failed: %s", module->path, + msg_err_config ("load of %s failed: %s", module->path, lua_tostring (L, -1)); cur = g_list_next (cur); + g_string_free (tb, TRUE); + lua_pop (L, 1); /* Error function */ continue; } @@ -316,21 +325,18 @@ rspamd_init_lua_filters (struct rspamd_config *cfg) *pcfg = cfg; lua_setglobal (L, "rspamd_config"); - /* do the call (0 arguments, N result) */ - if (lua_pcall (L, 0, LUA_MULTRET, 0) != 0) { - msg_info_config ("init of %s failed: %s", module->path, - lua_tostring (L, -1)); + if (lua_pcall (L, 0, 0, err_idx) != 0) { + msg_err_config ("init of %s failed: %v", + module->path, + tb); cur = g_list_next (cur); + g_string_free (tb, TRUE); + lua_pop (L, 1); continue; } - if (lua_gettop (L) != 0) { - if (lua_tonumber (L, -1) == -1) { - msg_info_config ( - "%s returned -1 that indicates configuration error", - module->path); - } - lua_pop (L, lua_gettop (L)); - } + + g_string_free (tb, TRUE); + lua_pop (L, 1); /* Error function */ } cur = g_list_next (cur); } @@ -806,3 +812,23 @@ rspamd_lua_parse_table_arguments (lua_State *L, gint pos, return TRUE; } + +gint +rspamd_lua_traceback (lua_State *L) +{ + lua_Debug d; + GString *tb = lua_touserdata (L, lua_upvalueindex(1)); + const gchar *msg = lua_tostring (L, 1); + gint i = 1; + + g_string_append_printf (tb, "%s; trace:", msg); + + while (lua_getstack (L, i++, &d)) { + lua_getinfo (L, "nSl", &d); + g_string_append_printf (tb, " [%d]:{%s:%d - %s [%s]};", + i - 1, d.short_src, d.currentline, + (d.name ? d.name : "<unknown>"), d.what); + } + + return 0; +} diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h index 5321d0409..b2b2750b5 100644 --- a/src/lua/lua_common.h +++ b/src/lua/lua_common.h @@ -281,5 +281,6 @@ gboolean rspamd_lua_parse_table_arguments (lua_State *L, gint pos, GError **err, const gchar *extraction_pattern, ...); +gint rspamd_lua_traceback (lua_State *L); #endif /* WITH_LUA */ #endif /* RSPAMD_LUA_H */ diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index 43a6fb135..5f42a528c 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -872,56 +872,72 @@ lua_metric_symbol_callback (struct rspamd_task *task, gpointer ud) { struct lua_callback_data *cd = ud; struct rspamd_task **ptask; - gint level = lua_gettop (cd->L), nresults; + gint level = lua_gettop (cd->L), nresults, err_idx; + lua_State *L = cd->L; + GString *tb; + + tb = g_string_new (""); + lua_pushlightuserdata (L, tb); + lua_pushcclosure (L, &rspamd_lua_traceback, 1); + err_idx = lua_gettop (L); + + level ++; if (cd->cb_is_ref) { - lua_rawgeti (cd->L, LUA_REGISTRYINDEX, cd->callback.ref); + lua_rawgeti (L, LUA_REGISTRYINDEX, cd->callback.ref); } else { - lua_getglobal (cd->L, cd->callback.name); + lua_getglobal (L, cd->callback.name); } - ptask = lua_newuserdata (cd->L, sizeof (struct rspamd_task *)); - rspamd_lua_setclass (cd->L, "rspamd{task}", -1); + + ptask = lua_newuserdata (L, sizeof (struct rspamd_task *)); + rspamd_lua_setclass (L, "rspamd{task}", -1); *ptask = task; - if (lua_pcall (cd->L, 1, LUA_MULTRET, 0) != 0) { - msg_info_task ("call to (%s)%s failed: %s", cd->symbol, - cd->cb_is_ref ? "local function" : cd->callback.name, - lua_tostring (cd->L, -1)); - } + if (lua_pcall (L, 1, LUA_MULTRET, err_idx) != 0) { - nresults = lua_gettop (cd->L) - level; - if (nresults >= 1) { - /* Function returned boolean, so maybe we need to insert result? */ - gboolean res; - GList *opts = NULL; - gint i; - gdouble flag = 1.0; - - if (lua_type (cd->L, level + 1) == LUA_TBOOLEAN) { - res = lua_toboolean (cd->L, level + 1); - if (res) { - gint first_opt = 2; - - if (lua_type (cd->L, level + 2) == LUA_TNUMBER) { - flag = lua_tonumber (cd->L, level + 2); - /* Shift opt index */ - first_opt = 3; - } + msg_err_task ("call to (%s)%s failed: %v", cd->symbol, + cd->cb_is_ref ? "local function" : cd->callback.name, tb); + } + else { + nresults = lua_gettop (L) - level; + + if (nresults >= 1) { + /* Function returned boolean, so maybe we need to insert result? */ + gboolean res; + GList *opts = NULL; + gint i; + gdouble flag = 1.0; + + if (lua_type (cd->L, level + 1) == LUA_TBOOLEAN) { + res = lua_toboolean (L, level + 1); + if (res) { + gint first_opt = 2; + + if (lua_type (L, level + 2) == LUA_TNUMBER) { + flag = lua_tonumber (L, level + 2); + /* Shift opt index */ + first_opt = 3; + } - for (i = lua_gettop (cd->L); i >= level + first_opt; i --) { - if (lua_type (cd->L, i) == LUA_TSTRING) { - const char *opt = lua_tostring (cd->L, i); + for (i = lua_gettop (L); i >= level + first_opt; i--) { + if (lua_type (L, i) == LUA_TSTRING) { + const char *opt = lua_tostring (L, i); - opts = g_list_prepend (opts, - rspamd_mempool_strdup (task->task_pool, opt)); + opts = g_list_prepend (opts, + rspamd_mempool_strdup (task->task_pool, + opt)); + } } + rspamd_task_insert_result (task, cd->symbol, flag, opts); } - rspamd_task_insert_result (task, cd->symbol, flag, opts); } + lua_pop (L, nresults); } - lua_pop (cd->L, nresults); } + + g_string_free (tb, TRUE); + lua_pop (L, 1); /* Error function */ } static gint |