Pārlūkot izejas kodu

Print stack trace on lua errors.

tags/1.0.0
Vsevolod Stakhov pirms 8 gadiem
vecāks
revīzija
92a1256394
3 mainītis faili ar 91 papildinājumiem un 48 dzēšanām
  1. 39
    13
      src/lua/lua_common.c
  2. 1
    0
      src/lua/lua_common.h
  3. 51
    35
      src/lua/lua_config.c

+ 39
- 13
src/lua/lua_common.c Parādīt failu

@@ -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;
}

+ 1
- 0
src/lua/lua_common.h Parādīt failu

@@ -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 */

+ 51
- 35
src/lua/lua_config.c Parādīt failu

@@ -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

Notiek ielāde…
Atcelt
Saglabāt