From: Egor Elchinov via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: gorcunov@tarantool.org, alyapunov@tarantool.org Cc: tarantool-patches@dev.tarantool.org, Egor Elchinov <elchinov.es@gmail.com> Subject: [Tarantool-patches] [PATCH v2 3/4] fiber: refactor lua backtrace routines Date: Fri, 9 Jul 2021 14:03:52 +0300 [thread overview] Message-ID: <731388d8274f1c36107202cd419516d44c7e3453.1625827535.git.elchinov.es@gmail.com> (raw) In-Reply-To: <cover.1625827535.git.elchinov.es@gmail.com> From: Egor Elchinov <elchinov.es@gmail.com> 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 | 167 +++++++++++++++++++++--------------------------- 1 file changed, 74 insertions(+), 93 deletions(-) diff --git a/src/lua/fiber.c b/src/lua/fiber.c index 8e96059b4..d0cdb0ae4 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); + #ifdef 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; @@ -1111,7 +1092,7 @@ static const struct luaL_Reg fiberlib[] = { {"top_enable", lbox_fiber_top_enable}, {"top_disable", lbox_fiber_top_disable}, #endif /* ENABLE_FIBER_TOP */ -#if ENABLE_BACKTRACE +#ifdef ENABLE_BACKTRACE {"parent_bt_enable", lbox_fiber_parent_bt_enable}, {"parent_bt_disable", lbox_fiber_parent_bt_disable}, #endif /* ENABLE_BACKTRACE */ -- 2.31.1
next prev parent reply other threads:[~2021-07-09 11:05 UTC|newest] Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-07-09 11:03 [Tarantool-patches] [PATCH v2 0/4] fiber: introduce creation backtrace Egor Elchinov via Tarantool-patches 2021-07-09 11:03 ` [Tarantool-patches] [PATCH v2 1/4] fiber: add PoC for fiber " Egor Elchinov via Tarantool-patches 2021-07-12 11:42 ` Cyrill Gorcunov via Tarantool-patches 2021-07-09 11:03 ` [Tarantool-patches] [PATCH v2 2/4] fiber: add option and PoC for Lua parent backtrace Egor Elchinov via Tarantool-patches 2021-07-12 12:09 ` Cyrill Gorcunov via Tarantool-patches 2021-07-14 9:29 ` Egor Elchinov via Tarantool-patches 2021-07-09 11:03 ` Egor Elchinov via Tarantool-patches [this message] 2021-07-12 12:13 ` [Tarantool-patches] [PATCH v2 3/4] fiber: refactor lua backtrace routines Cyrill Gorcunov via Tarantool-patches 2021-07-14 9:42 ` Egor Elchinov via Tarantool-patches 2021-07-09 11:03 ` [Tarantool-patches] [PATCH v2 4/4] fiber: refactor C backtrace and add changelog Egor Elchinov via Tarantool-patches 2021-07-12 12:35 ` Cyrill Gorcunov via Tarantool-patches 2021-07-14 9:42 ` 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=731388d8274f1c36107202cd419516d44c7e3453.1625827535.git.elchinov.es@gmail.com \ --to=tarantool-patches@dev.tarantool.org \ --cc=alyapunov@tarantool.org \ --cc=eelchinov@tarantool.org \ --cc=elchinov.es@gmail.com \ --cc=gorcunov@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 3/4] fiber: refactor lua backtrace routines' \ /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