From: Georgy Kirichenko <georgy@tarantool.org> To: tarantool-patches@freelists.org Cc: Georgy Kirichenko <georgy@tarantool.org> Subject: [tarantool-patches] [PATCH 3/3] Show names of Lua functions in backtraces Date: Fri, 21 Sep 2018 16:20:55 +0300 [thread overview] Message-ID: <76f2b7de46d4a1d55a3d2b7b39eb87172749eed6.1537535602.git.georgy@tarantool.org> (raw) In-Reply-To: <cover.1537535602.git.georgy@tarantool.org> Trace corresponding Lua state as well as normal C stack frames while fiber backtracing. This might be useful for debugging purposes. Fixes: #3538 --- src/lua/fiber.c | 86 +++++++++++++++++++++++++++++++++++------ test/app/fiber.result | 33 ++++++++++++++++ test/app/fiber.test.lua | 12 ++++++ 3 files changed, 120 insertions(+), 11 deletions(-) diff --git a/src/lua/fiber.c b/src/lua/fiber.c index 147add89b..289d240f6 100644 --- a/src/lua/fiber.c +++ b/src/lua/fiber.c @@ -178,20 +178,79 @@ lbox_fiber_id(struct lua_State *L) return 1; } +/** + * Lua fiber traceback context. + */ +struct lua_fiber_tb_ctx { + /* Lua stack to push values. */ + struct lua_State *L; + /* Lua stack to trace. */ + struct lua_State *R; + /* Current Lua frame. */ + int lua_frame; + /* Count of traced frames (both C and Lua). */ + int tb_frame; +}; + #ifdef ENABLE_BACKTRACE -static int -fiber_backtrace_cb(int frameno, void *frameret, const char *func, size_t offset, void *cb_ctx) +static void +dump_lua_frame(struct lua_State *L, lua_Debug *ar, int tb_frame, int lua_frame) { char buf[512]; - int l = snprintf(buf, sizeof(buf), "#%-2d %p in ", frameno, frameret); - if (func) - snprintf(buf + l, sizeof(buf) - l, "%s+%zu", func, offset); - else - snprintf(buf + l, sizeof(buf) - l, "?"); - struct lua_State *L = (struct lua_State*)cb_ctx; - lua_pushnumber(L, frameno + 1); + snprintf(buf, sizeof(buf), "LUA:#%d %s in %s at line %i", + lua_frame + 1, + ar->name != NULL ? ar->name : "(unnamed)", + ar->source, ar->currentline); + lua_pushnumber(L, tb_frame); lua_pushstring(L, buf); lua_settable(L, -3); +} + +static int +fiber_backtrace_cb(int frameno, void *frameret, const char *func, size_t offset, void *cb_ctx) +{ + struct lua_fiber_tb_ctx *tb_ctx = (struct lua_fiber_tb_ctx *)cb_ctx; + struct lua_State *L = tb_ctx->L; + if (strstr(func, "lj_BC_FUNCC") == func) { + // LUA code. + lua_Debug ar; + while (tb_ctx->R && lua_getstack(tb_ctx->R, tb_ctx->lua_frame, &ar) > 0) { + // Skip all C-frames. + lua_getinfo(tb_ctx->R, "Sln", &ar); + if (*ar.what != 'C') + break; + if (ar.name != NULL) { + // Dump frame if it is a built-in call + tb_ctx->tb_frame++; + dump_lua_frame(L, &ar, tb_ctx->tb_frame, + tb_ctx->lua_frame); + } + tb_ctx->lua_frame++; + } + while (tb_ctx->R && lua_getstack(tb_ctx->R, tb_ctx->lua_frame, &ar) > 0) { + // Trace Lua frames. + lua_getinfo(tb_ctx->R, "Sln", &ar); + if (*ar.what == 'C') { + break; + } + tb_ctx->tb_frame++; + dump_lua_frame(L, &ar, tb_ctx->tb_frame, + tb_ctx->lua_frame); + tb_ctx->lua_frame++; + } + } else { + char buf[512]; + int l = snprintf(buf, sizeof(buf), "C:#%d %p in ", + frameno + 1, frameret); + if (func) + snprintf(buf + l, sizeof(buf) - l, "%s+%zu", func, offset); + else + snprintf(buf + l, sizeof(buf) - l, "?"); + tb_ctx->tb_frame++; + lua_pushnumber(L, tb_ctx->tb_frame); + lua_pushstring(L, buf); + lua_settable(L, -3); + } return 0; } #endif @@ -229,10 +288,15 @@ lbox_fiber_statof(struct fiber *f, void *cb_ctx, bool backtrace) if (backtrace) { #ifdef ENABLE_BACKTRACE + struct lua_fiber_tb_ctx tb_ctx; + tb_ctx.L = L; + tb_ctx.R = f->storage.lua.stack; + tb_ctx.lua_frame = 0; + tb_ctx.tb_frame = 0; lua_pushstring(L, "backtrace"); lua_newtable(L); - if (f != fiber()) - backtrace_foreach(fiber_backtrace_cb, &f->ctx, L); + backtrace_foreach(fiber_backtrace_cb, + f != fiber() ? &f->ctx : NULL, &tb_ctx); lua_settable(L, -3); #endif /* ENABLE_BACKTRACE */ } diff --git a/test/app/fiber.result b/test/app/fiber.result index 77144e661..1a7827fa1 100644 --- a/test/app/fiber.result +++ b/test/app/fiber.result @@ -849,6 +849,39 @@ f2:cancel() f3:cancel() --- ... +function sf1() loop() end +--- +... +function sf2() sf1() end +--- +... +function sf3() sf2() end +--- +... +f1 = fiber.create(sf3) +--- +... +info = fiber.info() +--- +... +backtrace = info[f1:id()].backtrace +--- +... +bt_str = table.concat(backtrace, '\n') +--- +... +bt_str:find('sf1') ~= nil +--- +- true +... +bt_str:find('loop') ~= nil +--- +- true +... +bt_str:find('sf3') ~= nil +--- +- true +... -- # gh-666: nulls in output -- getmetatable(fiber.info()) diff --git a/test/app/fiber.test.lua b/test/app/fiber.test.lua index 98a136090..9df751cc8 100644 --- a/test/app/fiber.test.lua +++ b/test/app/fiber.test.lua @@ -334,6 +334,18 @@ f1:cancel() f2:cancel() f3:cancel() +function sf1() loop() end +function sf2() sf1() end +function sf3() sf2() end +f1 = fiber.create(sf3) + +info = fiber.info() +backtrace = info[f1:id()].backtrace +bt_str = table.concat(backtrace, '\n') +bt_str:find('sf1') ~= nil +bt_str:find('loop') ~= nil +bt_str:find('sf3') ~= nil + -- # gh-666: nulls in output -- getmetatable(fiber.info()) -- 2.19.0
next prev parent reply other threads:[~2018-09-21 13:21 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-09-21 13:20 [tarantool-patches] [PATCH 0/3] Dump lua frames for a fiber traceback Georgy Kirichenko 2018-09-21 13:20 ` [tarantool-patches] [PATCH 1/3] Set a lua state for the main fiber too Georgy Kirichenko 2018-09-25 23:27 ` [tarantool-patches] " Konstantin Osipov 2018-10-05 15:04 ` [tarantool-patches] " Vladimir Davydov 2018-09-21 13:20 ` [tarantool-patches] [PATCH 2/3] Proper unwind for currently executing fiber Georgy Kirichenko 2018-09-25 23:34 ` [tarantool-patches] " Konstantin Osipov 2018-09-26 6:57 ` Georgy Kirichenko 2018-09-26 17:36 ` Konstantin Osipov 2018-10-04 7:44 ` [tarantool-patches] " Georgy Kirichenko 2018-10-04 22:27 ` [tarantool-patches] " Konstantin Osipov 2018-10-05 15:09 ` [tarantool-patches] " Vladimir Davydov 2018-09-21 13:20 ` Georgy Kirichenko [this message] 2018-09-25 23:38 ` [tarantool-patches] Re: [PATCH 3/3] Show names of Lua functions in backtraces Konstantin Osipov 2018-10-04 7:55 ` [tarantool-patches] " Georgy Kirichenko 2018-10-04 22:28 ` [tarantool-patches] " Konstantin Osipov 2018-10-05 17:49 ` [tarantool-patches] " Vladimir Davydov 2018-10-10 16:39 [tarantool-patches] [PATCH v2 0/3] Dump lua frames for a fiber traceback Georgy Kirichenko 2018-10-10 16:39 ` [tarantool-patches] [PATCH 3/3] Show names of Lua functions in backtraces Georgy Kirichenko
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=76f2b7de46d4a1d55a3d2b7b39eb87172749eed6.1537535602.git.georgy@tarantool.org \ --to=georgy@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH 3/3] Show names of Lua functions in backtraces' \ /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