aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-09-14 21:37:34 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-09-14 21:37:34 +0100
commit92a1256394cde1ae5210fbfdcef78159b73b3ac2 (patch)
treef7efb17d5833b85766ea772c9a2ba2848f005bc8 /src
parent03b7a344fd6ab43449763f6c75cafffb1228fe65 (diff)
downloadrspamd-92a1256394cde1ae5210fbfdcef78159b73b3ac2.tar.gz
rspamd-92a1256394cde1ae5210fbfdcef78159b73b3ac2.zip
Print stack trace on lua errors.
Diffstat (limited to 'src')
-rw-r--r--src/lua/lua_common.c52
-rw-r--r--src/lua/lua_common.h1
-rw-r--r--src/lua/lua_config.c86
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