Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH luajit v1] tools: fix luajit-gdb stack dump
@ 2021-06-18  6:22 Sergey Kaplun via Tarantool-patches
  2021-07-05  7:03 ` Sergey Kaplun via Tarantool-patches
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2021-06-18  6:22 UTC (permalink / raw)
  To: Sergey Ostanevich, Igor Munkin; +Cc: tarantool-patches

When there is only one frame (so-called dummy frame) with a dummy thread
on stack bottom at L->base - 1 - LJ_FR2, stack dump does not show stack
slots from bottom to top, because the frame link is already pointed to
stack bottom (dummy thread mentioned above). Its output looks like the
following:

| 0x7fb512ac40:0x7fb512ac70 [    ] 7 slots: Red zone
| 0x7fb512ac38            [   M]
| 0x7fb512ab28:0x7fb512ac30 [    ] 34 slots: Free stack slots
| 0x7fb512ab20            [  T ]
| 0x7fb512ab08:0x7fb512ab10 [S   ] FRAME: dummy L

This patch unrolled first loop iteration. Stack dump first inspect all
fields for the top frame and then continue if there are other frames.
After patch the output looks like the following:

| 0x7fb512ac40:0x7fb512ac70 [    ] 7 slots: Red zone
| 0x7fb512ac38            [   M]
| 0x7fb512ab28:0x7fb512ac30 [    ] 34 slots: Free stack slots
| 0x7fb512ab20            [  T ]
| 0x7fb512ab18            [    ] VALUE: string 0 "/tmp/net_box.lua:6: err in ser" @ 0x7fb512ade8
| 0x7fb512ab10            [ B  ] VALUE: table @ 0x7fb512ac80 (asize: 0, hmask: 0x0)
| 0x7fb512ab00:0x7fb512ab08 [S   ] FRAME: dummy L
---

Branch: https://github.com/tarantool/luajit/tree/skaplun/fix-luajit-gdb

Steps to test behaviour:
0) Clone branch
1) Build tarantool with GC64 or not (I've tested both cases)
2) Run the following script </tmp/net_box.lua> by Tarantool via gdb.

| $ cat /tmp/netbox.lua
| box.cfg{log_level = 50, listen = "127.0.0.1:3802"}
| box.schema.user.grant('guest','read,write,execute','universe', nil, {if_not_exists=true})
| local net_box = require"net.box"
| local cn = net_box:connect("127.0.0.1:3802")
| local function f()
|   return setmetatable({}, {__serialize = function() error[[err in ser]] end})
| end
| _G.f = f
| local r, st = cn:call("f")
| print(r,st)

| $ gdb --args ./tarantool /tmp/netbox.lua
| ...
| (gdb) source ~/builds_workspace/luajit/fix-luajit-gdb/src/luajit-gdb.py
| ...

3) Set breakpoint to ./src/lua/msgpack.c:234, and run

| (gdb) b ./src/lua/msgpack.c:234

I'm not sure about your sources version, so you can just set breakpoin to
mp_encode(), run and continue (need two entries). We are interested in
the line #234:

| 233|.......if (luaL_tofield(L, cfg, opts, lua_gettop(L), &field) < 0)
| 234|.......|.......return luaT_error(L);

And dump the stack:

| (gdb) lj-stack L
| 0x7fb512ac40:0x7fb512ac70 [    ] 7 slots: Red zone
| 0x7fb512ac38            [   M]
| 0x7fb512ab28:0x7fb512ac30 [    ] 34 slots: Free stack slots
| 0x7fb512ab20            [  T ]
| 0x7fb512ab18            [    ] VALUE: string 0 "/tmp/net_box.lua:6: err in ser" @ 0x7fb512ade8
| 0x7fb512ab10            [ B  ] VALUE: table @ 0x7fb512ac80 (asize: 0, hmask: 0x0)
| 0x7fb512ab00:0x7fb512ab08 [S   ] FRAME: dummy L

 src/luajit-gdb.py | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/luajit-gdb.py b/src/luajit-gdb.py
index f1fd6230..a3dad585 100644
--- a/src/luajit-gdb.py
+++ b/src/luajit-gdb.py
@@ -424,16 +424,26 @@ def dump_stack(L, base=None, top=None):
         )
     ]) + '\n'
 
+    # Set framelink for the top frame. Dump frame slots even for dummy frame.
     slot = top - 1
     framelink = base - (1 + LJ_FR2)
+    while slot > framelink + LJ_FR2:
+        dump += dump_stack_slot(L, slot, base, top)
+        slot -= 1
 
+    # If there are other frames -- continue.
     while framelink > mref('TValue *', L['stack']):
-        while slot > framelink + LJ_FR2:
-            dump += dump_stack_slot(L, slot, base, top)
-            slot -= 1
+        assert slot == framelink + LJ_FR2, "Invalid slot during frame unwind"
         dump += dump_framelink(L, framelink)
         framelink = frame_prev(framelink + LJ_FR2) - LJ_FR2
         slot -= 1 + LJ_FR2
+        while slot > framelink + LJ_FR2:
+            dump += dump_stack_slot(L, slot, base, top)
+            slot -= 1
+
+    assert slot == framelink + LJ_FR2, "Invalid slot after frame unwind"
+    # Skip nil slot for the last frame for 2-slot frames.
+    slot -= LJ_FR2
 
     dump += '{fr}{padding} [S   ] FRAME: dummy L'.format(
         fr = slot,
-- 
2.31.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-07-22 13:58 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-18  6:22 [Tarantool-patches] [PATCH luajit v1] tools: fix luajit-gdb stack dump Sergey Kaplun via Tarantool-patches
2021-07-05  7:03 ` Sergey Kaplun via Tarantool-patches
2021-07-20 12:29 ` Igor Munkin via Tarantool-patches
2021-07-21  8:49   ` Sergey Kaplun via Tarantool-patches
2021-07-21  8:54     ` Igor Munkin via Tarantool-patches
2021-07-22 10:32       ` Sergey Ostanevich via Tarantool-patches
2021-07-22 11:48         ` Igor Munkin via Tarantool-patches
2021-07-22 12:51           ` Sergey Ostanevich via Tarantool-patches
2021-07-21  9:02     ` Sergey Kaplun via Tarantool-patches
2021-07-22 13:34 ` Igor Munkin via Tarantool-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox