From: Georgy Kirichenko <georgy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: Georgy Kirichenko <georgy@tarantool.org>
Subject: [tarantool-patches] [PATCH v3 4/4] Show names of Lua functions in backtraces
Date: Wed, 31 Oct 2018 13:49:13 +0300 [thread overview]
Message-ID: <54488ded8f4e686707d4c1bafb4da803f521c622.1540982711.git.georgy@tarantool.org> (raw)
In-Reply-To: <cover.1540982711.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 | 73 ++++++++++++++++++++++++++++++++++++++---
test/app/fiber.result | 36 ++++++++++++++++++++
test/app/fiber.test.lua | 13 ++++++++
3 files changed, 118 insertions(+), 4 deletions(-)
diff --git a/src/lua/fiber.c b/src/lua/fiber.c
index 147add89b..7ed341924 100644
--- a/src/lua/fiber.c
+++ b/src/lua/fiber.c
@@ -178,20 +178,80 @@ 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 void
+dump_lua_frame(struct lua_State *L, lua_Debug *ar, 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);
+ lua_pushnumber(L, tb_frame);
+ lua_newtable(L);
+ lua_pushstring(L, "L");
+ lua_pushstring(L, buf);
+ lua_settable(L, -3);
+ 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) {
+ /* 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++;
+ }
+ }
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);
+ tb_ctx->tb_frame++;
+ lua_pushnumber(L, tb_ctx->tb_frame);
+ lua_newtable(L);
+ lua_pushstring(L, "C");
lua_pushstring(L, buf);
lua_settable(L, -3);
+ lua_settable(L, -3);
return 0;
}
#endif
@@ -229,10 +289,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..59aa8d5c6 100644
--- a/test/app/fiber.result
+++ b/test/app/fiber.result
@@ -849,6 +849,42 @@ 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 = ''
+---
+...
+for _, b in pairs(backtrace) do bt_str = bt_str .. (b['L'] or '') end
+---
+...
+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..b9d82ef05 100644
--- a/test/app/fiber.test.lua
+++ b/test/app/fiber.test.lua
@@ -334,6 +334,19 @@ 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 = ''
+for _, b in pairs(backtrace) do bt_str = bt_str .. (b['L'] or '') end
+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.1
next prev parent reply other threads:[~2018-10-31 10:49 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-31 10:49 [tarantool-patches] [PATCH v3 0/4] Dump lua frames for a fiber traceback Georgy Kirichenko
2018-10-31 10:49 ` [tarantool-patches] [PATCH v3 1/4] fiber: do not inline coro unwind function Georgy Kirichenko
2018-10-31 10:49 ` [tarantool-patches] [PATCH v3 2/4] Proper unwind for currently executing fiber Georgy Kirichenko
2018-10-31 10:49 ` [tarantool-patches] [PATCH v3 3/4] Use fiber lua state for triggers if possible Georgy Kirichenko
2018-10-31 10:49 ` Georgy Kirichenko [this message]
2018-11-01 12:45 ` [tarantool-patches] [PATCH v3 0/4] Dump lua frames for a fiber traceback Vladimir Davydov
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=54488ded8f4e686707d4c1bafb4da803f521c622.1540982711.git.georgy@tarantool.org \
--to=georgy@tarantool.org \
--cc=tarantool-patches@freelists.org \
--subject='Re: [tarantool-patches] [PATCH v3 4/4] 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