From: Leonid Vasiliev <lvasiliev@tarantool.org> To: v.shpilevoy@tarantool.org Cc: tarantool-patches@dev.tarantool.org Subject: [Tarantool-patches] [PATCH v2 1/5] error: Add a Lua backtrace to error Date: Fri, 10 Apr 2020 11:10:39 +0300 [thread overview] Message-ID: <e3ac4d221f1a2a513cbaf64fc429a84458b8e977.1586505741.git.lvasiliev@tarantool.org> (raw) In-Reply-To: <cover.1586505741.git.lvasiliev@tarantool.org> In-Reply-To: <cover.1586505741.git.lvasiliev@tarantool.org> In accordance with https://github.com/tarantool/tarantool/issues/4398 Lua traceback has been added for box.error. Has been added a per server flag for turn on/off traceback adding and ability to force it at creation time. @TarantoolBot document Title: error.traceback Was added: Per server flag for turn on/off adding a traceback to the errors. box.error.cfg({traceback_supplementation = true/false}) Adding a traceback can be forced on creation. box.error.new({type = "CustomType", reason = "reason", traceback = true/false}) Needed for #4398 --- src/box/lua/error.cc | 33 ++++++++++++++++++++++++++++++++- src/lib/core/diag.c | 32 ++++++++++++++++++++++++++++++++ src/lib/core/diag.h | 11 +++++++++++ src/lib/core/exception.cc | 1 + src/lua/error.c | 10 ++++++++++ src/lua/error.lua | 12 +++++++++++- test/app/fiber.result | 5 +++-- test/box/error.result | 5 +++-- test/engine/func_index.result | 10 ++++++---- 9 files changed, 109 insertions(+), 10 deletions(-) diff --git a/src/box/lua/error.cc b/src/box/lua/error.cc index b2625bf..4432bc8 100644 --- a/src/box/lua/error.cc +++ b/src/box/lua/error.cc @@ -54,6 +54,8 @@ luaT_error_create(lua_State *L, int top_base) { uint32_t code = 0; const char *reason = NULL; + bool tb_parsed = false; + bool tb_mode = false; const char *file = ""; unsigned line = 0; lua_Debug info; @@ -87,6 +89,12 @@ luaT_error_create(lua_State *L, int top_base) if (reason == NULL) reason = ""; lua_pop(L, 1); + lua_getfield(L, top_base, "traceback"); + if (lua_isboolean(L, -1)) { + tb_parsed = true; + tb_mode = lua_toboolean(L, -1); + } + lua_pop(L, -1); } else { return NULL; } @@ -102,7 +110,12 @@ raise: } line = info.currentline; } - return box_error_new(file, line, code, "%s", reason); + + struct error *err = box_error_new(file, line, code, "%s", reason); + if (tb_parsed) + err->traceback_mode = tb_mode; + + return err; } static int @@ -180,6 +193,20 @@ luaT_error_set(struct lua_State *L) } static int +luaT_error_cfg(struct lua_State *L) +{ + if (lua_gettop(L) < 1 || !lua_istable(L, 1)) + return luaL_error(L, "Usage: box.error.cfg({}})"); + + lua_getfield(L, 1, "traceback_supplementation"); + if (lua_isnil(L, -1) == 0) + error_set_traceback_supplementation(lua_toboolean(L, -1)); + lua_pop(L, 1); + + return 0; +} + +static int lbox_errinj_set(struct lua_State *L) { char *name = (char*)luaL_checkstring(L, 1); @@ -297,6 +324,10 @@ box_lua_error_init(struct lua_State *L) { lua_pushcfunction(L, luaT_error_set); lua_setfield(L, -2, "set"); } + { + lua_pushcfunction(L, luaT_error_cfg); + lua_setfield(L, -2, "cfg"); + } lua_setfield(L, -2, "__index"); } lua_setmetatable(L, -2); diff --git a/src/lib/core/diag.c b/src/lib/core/diag.c index e143db1..1caa75e 100644 --- a/src/lib/core/diag.c +++ b/src/lib/core/diag.c @@ -31,6 +31,11 @@ #include "diag.h" #include "fiber.h" +/** + * Global flag to add or not backtrace to errors. + */ +static bool global_traceback_mode = false; + int error_set_prev(struct error *e, struct error *prev) { @@ -97,6 +102,8 @@ error_create(struct error *e, e->errmsg[0] = '\0'; e->cause = NULL; e->effect = NULL; + e->lua_traceback = NULL; + e->traceback_mode = global_traceback_mode; } struct diag * @@ -120,3 +127,28 @@ error_vformat_msg(struct error *e, const char *format, va_list ap) vsnprintf(e->errmsg, sizeof(e->errmsg), format, ap); } +void +error_set_lua_traceback(struct error *e, const char *lua_traceback) +{ + if (e == NULL) + return; + + if (lua_traceback == NULL) { + free(e->lua_traceback); + e->lua_traceback = NULL; + return; + } + + size_t tb_len = strlen(lua_traceback); + e->lua_traceback = realloc(e->lua_traceback, tb_len + 1); + if (e->lua_traceback == NULL) + return; + strcpy(e->lua_traceback, lua_traceback); + return; +} + +void +error_set_traceback_supplementation(bool traceback_mode) +{ + global_traceback_mode = traceback_mode; +} diff --git a/src/lib/core/diag.h b/src/lib/core/diag.h index 7a5454d..f38009c 100644 --- a/src/lib/core/diag.h +++ b/src/lib/core/diag.h @@ -110,6 +110,8 @@ struct error { */ struct error *cause; struct error *effect; + char *lua_traceback; + bool traceback_mode; }; static inline void @@ -197,6 +199,15 @@ error_format_msg(struct error *e, const char *format, ...); void error_vformat_msg(struct error *e, const char *format, va_list ap); +void +error_set_lua_traceback(struct error *e, const char *lua_traceback); + +/** +* Sets the global flag to add or not backtrace to errors. +*/ +void +error_set_traceback_supplementation(bool traceback_mode); + /** * Diagnostics Area - a container for errors */ diff --git a/src/lib/core/exception.cc b/src/lib/core/exception.cc index 180cb0e..0e4b6ca 100644 --- a/src/lib/core/exception.cc +++ b/src/lib/core/exception.cc @@ -42,6 +42,7 @@ extern "C" { static void exception_destroy(struct error *e) { + free(e->lua_traceback); delete (Exception *) e; } diff --git a/src/lua/error.c b/src/lua/error.c index 18a990a..cd6ab54 100644 --- a/src/lua/error.c +++ b/src/lua/error.c @@ -85,6 +85,16 @@ luaT_pusherror(struct lua_State *L, struct error *e) * then set the finalizer. */ error_ref(e); + + if (e->lua_traceback == NULL && e->traceback_mode) { + int top = lua_gettop(L); + luaL_traceback(L, L, NULL, 0); + if (lua_isstring(L, -1)) { + error_set_lua_traceback(e, lua_tostring(L, -1)); + } + lua_settop(L, top); + } + assert(CTID_CONST_STRUCT_ERROR_REF != 0); struct error **ptr = (struct error **) luaL_pushcdata(L, CTID_CONST_STRUCT_ERROR_REF); diff --git a/src/lua/error.lua b/src/lua/error.lua index bdc9c71..46d2866 100644 --- a/src/lua/error.lua +++ b/src/lua/error.lua @@ -26,6 +26,8 @@ struct error { char _errmsg[DIAG_ERRMSG_MAX]; struct error *_cause; struct error *_effect; + char *lua_traceback; + bool traceback_mode; }; char * @@ -92,6 +94,14 @@ local function error_trace(err) } end +local function error_traceback(err) + local result = "Traceback is absent" + if err.lua_traceback ~= ffi.nullptr then + result = ffi.string(err.lua_traceback) + end + return result +end + local function error_errno(err) local e = err._saved_errno if e == 0 then @@ -122,7 +132,6 @@ local function error_set_prev(err, prev) if ok ~= 0 then error("Cycles are not allowed") end - end local error_fields = { @@ -131,6 +140,7 @@ local error_fields = { ["trace"] = error_trace; ["errno"] = error_errno; ["prev"] = error_prev; + ["traceback"] = error_traceback; } local function error_unpack(err) diff --git a/test/app/fiber.result b/test/app/fiber.result index debfc67..fc6b3c9 100644 --- a/test/app/fiber.result +++ b/test/app/fiber.result @@ -1038,12 +1038,13 @@ st; ... e:unpack(); --- -- type: ClientError +- traceback: Traceback is absent code: 1 - message: Illegal parameters, oh my trace: - file: '[string "function err() box.error(box.error.ILLEGAL_PA..."]' line: 1 + type: ClientError + message: Illegal parameters, oh my ... flag = false; --- diff --git a/test/box/error.result b/test/box/error.result index 234c263..22788a1 100644 --- a/test/box/error.result +++ b/test/box/error.result @@ -34,12 +34,13 @@ e | ... e:unpack() | --- - | - type: ClientError + | - traceback: Traceback is absent | code: 1 - | message: Illegal parameters, bla bla | trace: | - file: '[C]' | line: 4294967295 + | type: ClientError + | message: Illegal parameters, bla bla | ... e.type | --- diff --git a/test/engine/func_index.result b/test/engine/func_index.result index a827c92..28befca 100644 --- a/test/engine/func_index.result +++ b/test/engine/func_index.result @@ -276,7 +276,8 @@ e = box.error.last() | ... e:unpack() | --- - | - code: 198 + | - traceback: Traceback is absent + | code: 198 | trace: | - file: <filename> | line: <line> @@ -291,12 +292,13 @@ e = e.prev | ... e:unpack() | --- - | - type: LuajitError - | message: '[string "return function(tuple) local ..."]:1: attempt - | to call global ''require'' (a nil value)' + | - traceback: Traceback is absent | trace: | - file: <filename> | line: <line> + | type: LuajitError + | message: '[string "return function(tuple) local ..."]:1: attempt + | to call global ''require'' (a nil value)' | ... e = e.prev | --- -- 2.7.4
next prev parent reply other threads:[~2020-04-10 8:10 UTC|newest] Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-04-10 8:10 [Tarantool-patches] [PATCH v2 0/5] Extending error functionality Leonid Vasiliev 2020-04-10 8:10 ` Leonid Vasiliev [this message] 2020-04-14 1:11 ` [Tarantool-patches] [PATCH v2 1/5] error: Add a Lua backtrace to error Vladislav Shpilevoy 2020-04-15 9:25 ` lvasiliev 2020-04-16 0:00 ` Vladislav Shpilevoy 2020-04-16 1:11 ` Alexander Turenko 2020-04-16 8:58 ` lvasiliev 2020-04-16 9:30 ` Alexander Turenko 2020-04-16 12:27 ` lvasiliev 2020-04-16 12:45 ` Alexander Turenko 2020-04-16 17:48 ` lvasiliev 2020-04-16 8:40 ` lvasiliev 2020-04-16 9:04 ` lvasiliev 2020-04-10 8:10 ` [Tarantool-patches] [PATCH v2 2/5] error: Add the custom error type Leonid Vasiliev 2020-04-14 1:11 ` Vladislav Shpilevoy 2020-04-15 9:25 ` lvasiliev 2020-04-16 0:02 ` Vladislav Shpilevoy 2020-04-16 9:18 ` lvasiliev 2020-04-16 21:03 ` Vladislav Shpilevoy 2020-04-10 8:10 ` [Tarantool-patches] [PATCH v2 3/5] error: Increase the number of fields transmitted through IPROTO Leonid Vasiliev 2020-04-14 1:12 ` Vladislav Shpilevoy 2020-04-15 9:25 ` lvasiliev 2020-04-16 0:02 ` Vladislav Shpilevoy 2020-04-10 8:10 ` [Tarantool-patches] [PATCH v2 4/5] iproto: Add session settings for IPROTO Leonid Vasiliev 2020-04-14 1:12 ` Vladislav Shpilevoy 2020-04-15 9:26 ` lvasiliev 2020-04-16 0:06 ` Vladislav Shpilevoy 2020-04-16 9:36 ` lvasiliev 2020-04-16 21:04 ` Vladislav Shpilevoy 2020-04-10 8:10 ` [Tarantool-patches] [PATCH v2 5/5] iproto: Update error MsgPack encoding Leonid Vasiliev 2020-04-14 1:12 ` Vladislav Shpilevoy 2020-04-15 9:25 ` lvasiliev 2020-04-16 0:11 ` Vladislav Shpilevoy 2020-04-16 10:04 ` lvasiliev 2020-04-16 21:06 ` Vladislav Shpilevoy 2020-04-14 1:10 ` [Tarantool-patches] [PATCH v2 0/5] Extending error functionality Vladislav Shpilevoy 2020-04-15 9:48 ` lvasiliev
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=e3ac4d221f1a2a513cbaf64fc429a84458b8e977.1586505741.git.lvasiliev@tarantool.org \ --to=lvasiliev@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 1/5] error: Add a Lua backtrace to error' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox