From: Egor Elchinov via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: tarantool-patches@dev.tarantool.org Cc: gorcunov@tarantool.org Subject: [Tarantool-patches] [PATCH 6/7] fiber: refactor lua backtrace routine Date: Thu, 1 Jul 2021 18:54:49 +0300 [thread overview] Message-ID: <c76380462ce397be29fea15f42143c796ca98d7f.1625153622.git.elchinov.es@gmail.com> (raw) In-Reply-To: <cover.1625153622.git.elchinov.es@gmail.com> From: Egor Elchinov <eelchinov@tarantool.org> Lua backtrace with callback moved to new routine `lua_backtrace_cb()` similar to the `backtrace_cb()` for C backtrace. Needed for: #4002 --- src/lua/fiber.c | 165 +++++++++++++++++++++--------------------------- 1 file changed, 73 insertions(+), 92 deletions(-) diff --git a/src/lua/fiber.c b/src/lua/fiber.c index fe01ae23b..9e0c33a8f 100644 --- a/src/lua/fiber.c +++ b/src/lua/fiber.c @@ -205,14 +205,17 @@ struct lua_parent_tb_ctx { int tb_frame; }; +/** Lua backtrace callback type */ +typedef int (lua_backtrace_cb)(struct lua_Debug *ar, int frame_no, void *cb_ctx); + #if ENABLE_BACKTRACE static void -dump_lua_frame(struct lua_State *L, lua_Debug *ar, int tb_frame) +dump_lua_frame(struct lua_State *L, const char *name, const char *src, int line, + int tb_frame) { char buf[512]; snprintf(buf, sizeof(buf), "%s in %s at line %i", - ar->name != NULL ? ar->name : "(unnamed)", - ar->source, ar->currentline); + name != NULL ? name : "(unnamed)", src, line); lua_pushnumber(L, tb_frame); lua_newtable(L); lua_pushstring(L, "L"); @@ -221,20 +224,65 @@ dump_lua_frame(struct lua_State *L, lua_Debug *ar, int tb_frame) lua_settable(L, -3); } +static int +dump_lua_frame_cb(lua_Debug *ar, int tb_frame, void *cb_ctx) +{ + (void) tb_frame; + struct lua_fiber_tb_ctx *tb_ctx = (struct lua_fiber_tb_ctx *)cb_ctx; + + tb_ctx->tb_frame++; + dump_lua_frame(tb_ctx->L, ar->name, ar->source, ar->currentline, + tb_ctx->tb_frame); + + return 0; +} + +static int +save_lua_frame_cb(lua_Debug *ar, int tb_frame, void *cb_ctx) +{ + struct parent_bt_lua *bt = (struct parent_bt_lua *)cb_ctx; + + if (tb_frame >= PARENT_BT_LUA_LEN_MAX) + return 1; + + bt->cnt++; + bt->lines[tb_frame] = ar->currentline; + strncpy(bt->names[tb_frame], ar->name == NULL ? "(unnamed)" : ar->name, + PARENT_BT_LUA_NAME_MAX - 1); + strncpy(bt->sources[tb_frame], ar->source, + PARENT_BT_LUA_NAME_MAX - 1); + + return 0; +} + static void -dump_parent_lua_frame(struct lua_State *L, const char *name, const char *src, - int currentline, int tb_frame) +lua_backtrace_foreach(struct lua_State *L, lua_backtrace_cb cb, void *cb_ctx) { - char buf[512]; - snprintf(buf, sizeof(buf), "%s in %s at line %i", - name != NULL ? name : "(unnamed)", - src, currentline); - lua_pushnumber(L, tb_frame); - lua_newtable(L); - lua_pushstring(L, "L"); - lua_pushstring(L, buf); - lua_settable(L, -3); - lua_settable(L, -3); + int lua_frame = 0, tb_frame = 0; + lua_Debug ar; + while (lua_getstack(L, lua_frame, &ar) > 0) { + /* Skip all following C-frames. */ + lua_getinfo(L, "Sln", &ar); + if (*ar.what != 'C') + break; + if (ar.name != NULL) { + /* Dump frame if it is a C built-in call. */ + if (cb(&ar, tb_frame, cb_ctx) != 0) + return; + tb_frame++; + } + lua_frame++; + } + while (lua_getstack(L, lua_frame, &ar) > 0) { + /* Trace Lua frame. */ + lua_getinfo(L, "Sln", &ar); + if (*ar.what == 'C') + break; + if (cb(&ar, tb_frame, cb_ctx) != 0) + return; + tb_frame++; + lua_frame++; + } } static int @@ -247,31 +295,9 @@ fiber_backtrace_cb(int frameno, void *frameret, const char *func, size_t offset, * https://github.com/tarantool/tarantool/issues/5326 * will not resolved, but is possible afterwards. */ - if (func != NULL && strstr(func, "lj_BC_FUNCC") == func) { + if (func != NULL && tb_ctx->R && strstr(func, "lj_BC_FUNCC") == func) { /* We are in the LUA vm. */ - lua_Debug ar; - while (tb_ctx->R && lua_getstack(tb_ctx->R, tb_ctx->lua_frame, &ar) > 0) { - /* Skip all following C-frames. */ - lua_getinfo(tb_ctx->R, "Sln", &ar); - if (*ar.what != 'C') - break; - if (ar.name != NULL) { - /* Dump frame if it is a C built-in call. */ - tb_ctx->tb_frame++; - dump_lua_frame(L, &ar, tb_ctx->tb_frame); - } - tb_ctx->lua_frame++; - } - while (tb_ctx->R && lua_getstack(tb_ctx->R, tb_ctx->lua_frame, &ar) > 0) { - /* Trace Lua frame. */ - 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++; - } + lua_backtrace_foreach(tb_ctx->R, dump_lua_frame_cb, tb_ctx); } char buf[512]; int l = snprintf(buf, sizeof(buf), "#%-2d %p in ", frameno, frameret); @@ -306,10 +332,10 @@ fiber_parent_backtrace_cb(int frameno, void *frameret, const char *func, /* We are in the LUA vm. */ while (lua_frame < bt->cnt) { tb_ctx->tb_frame++; - dump_parent_lua_frame(L, bt->names[lua_frame], - bt->sources[lua_frame], - bt->lines[lua_frame], - tb_ctx->tb_frame); + dump_lua_frame(L, bt->names[lua_frame], + bt->sources[lua_frame], + bt->lines[lua_frame], + tb_ctx->tb_frame); lua_frame++; } } @@ -332,60 +358,15 @@ fiber_parent_backtrace_cb(int frameno, void *frameret, const char *func, static int fiber_parent_bt_init(struct fiber *f, struct lua_State *L) { - int lua_frame = 0, tb_frame = 0; - lua_Debug ar; struct parent_bt_lua *bt = NULL; - - bt = (struct parent_bt_lua *)malloc(sizeof(*bt)); + bt = (struct parent_bt_lua *)calloc(1, sizeof(*bt)); if (bt == NULL){ - diag_set(OutOfMemory, sizeof(*bt), "malloc", "bt"); + diag_set(OutOfMemory, sizeof(*bt), "calloc", "bt"); return 1; } - while (tb_frame < PARENT_BT_LUA_LEN_MAX && - lua_getstack(L, lua_frame, &ar) > 0) { - /* Skip all following C-frames. */ - lua_getinfo(L, "Sln", &ar); - if (*ar.what != 'C') - break; - if (ar.name != NULL) { - /* Dump frame if it is a C built-in call. */ - bt->lines[tb_frame] = ar.currentline; - memset(bt->names[tb_frame], 0, - PARENT_BT_LUA_NAME_MAX); - strncpy(bt->names[tb_frame], ar.name, - PARENT_BT_LUA_NAME_MAX - 1); - memset(bt->sources[tb_frame], 0, - PARENT_BT_LUA_NAME_MAX); - strncpy(bt->sources[tb_frame], ar.source, - PARENT_BT_LUA_NAME_MAX - 1); - tb_frame++; - } - lua_frame++; - } - while (tb_frame < PARENT_BT_LUA_LEN_MAX && - lua_getstack(L, lua_frame, &ar) > 0) { - /* Trace Lua frame. */ - lua_getinfo(L, "Sln", &ar); - if (*ar.what == 'C') - break; - bt->lines[tb_frame] = ar.currentline; - memset(bt->names[tb_frame], 0, PARENT_BT_LUA_NAME_MAX); - if (ar.name != NULL) { - strncpy(bt->names[tb_frame], ar.name, - PARENT_BT_LUA_NAME_MAX - 1); - } else { - strncpy(bt->names[tb_frame], "(unnamed)", - PARENT_BT_LUA_NAME_MAX - 1); - } - memset(bt->sources[tb_frame], 0, PARENT_BT_LUA_NAME_MAX); - strncpy(bt->sources[tb_frame], ar.source, - PARENT_BT_LUA_NAME_MAX - 1); - tb_frame++; - lua_frame++; - } - - bt->cnt = tb_frame; + bt->cnt = 0; + lua_backtrace_foreach(L, save_lua_frame_cb, bt); f->storage.lua.parent_bt = bt; return 0; -- 2.31.1
next prev parent reply other threads:[~2021-07-01 15:58 UTC|newest] Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-07-01 15:54 [Tarantool-patches] [PATCH 0/7] fiber: introduce creation backtrace Egor Elchinov via Tarantool-patches 2021-07-01 15:54 ` [Tarantool-patches] [PATCH 1/7] fiber: add PoC for fiber " Egor Elchinov via Tarantool-patches 2021-07-01 15:54 ` [Tarantool-patches] [PATCH 2/7] fiber: fix DARWIN build Egor Elchinov via Tarantool-patches 2021-07-01 15:54 ` [Tarantool-patches] [PATCH 3/7] fiber: apply fix patch Egor Elchinov via Tarantool-patches 2021-07-01 15:54 ` [Tarantool-patches] [PATCH 4/7] fiber: add PoC for Lua parent backtrace Egor Elchinov via Tarantool-patches 2021-07-01 15:54 ` [Tarantool-patches] [PATCH 5/7] fiber: add dynamic option for " Egor Elchinov via Tarantool-patches 2021-07-01 15:54 ` Egor Elchinov via Tarantool-patches [this message] 2021-07-01 15:54 ` [Tarantool-patches] [PATCH 7/7] fiber: refactor C backtrace and add changelog Egor Elchinov via Tarantool-patches 2021-07-01 20:24 [Tarantool-patches] [PATCH 0/7] fiber: introduce creation backtrace Egor Elchinov via Tarantool-patches 2021-07-01 20:24 ` [Tarantool-patches] [PATCH 6/7] fiber: refactor lua backtrace routine Egor Elchinov via Tarantool-patches
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=c76380462ce397be29fea15f42143c796ca98d7f.1625153622.git.elchinov.es@gmail.com \ --to=tarantool-patches@dev.tarantool.org \ --cc=eelchinov@tarantool.org \ --cc=gorcunov@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH 6/7] fiber: refactor lua backtrace routine' \ /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