[Tarantool-patches] [PATCH luajit 2/4] gdb: make existing commands more verbose

Igor Munkin imun at tarantool.org
Mon Jan 27 23:41:06 MSK 2020


* Enrich GCtab object dumpers with array and hash parts sizes
* Make lj-state reporting the current JIT state

Signed-off-by: Igor Munkin <imun at tarantool.org>
---
 src/luajit-gdb.py | 63 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 14 deletions(-)

diff --git a/src/luajit-gdb.py b/src/luajit-gdb.py
index 633c56a..4f69152 100644
--- a/src/luajit-gdb.py
+++ b/src/luajit-gdb.py
@@ -155,6 +155,14 @@ def gcval(obj):
 def G(L):
     return mref('global_State *', L['glref'])
 
+def J(L):
+    typeGG = gtype('GG_State')
+
+    return cast('jit_State *', int(cast('char *', G(L)))
+        - int(typeGG['g'].bitpos / 8)
+        + int(typeGG['J'].bitpos / 8)
+    )
+
 def vm_state(L):
     return {
         i2notu64(0): 'INTERP',
@@ -164,7 +172,7 @@ def vm_state(L):
         i2notu64(4): 'RECORD',
         i2notu64(5): 'OPT',
         i2notu64(6): 'ASM',
-    }.get(int(tou64(G(L)['vmstate'])), 'TRACE')
+    }.get(int(tou64(g['vmstate'])), 'TRACE')
 
 def gc_state(L):
     return {
@@ -177,6 +185,17 @@ def gc_state(L):
         6: 'LAST',
     }.get(int(G(L)['gc']['state']), 'INVALID')
 
+def jit_state(L):
+    return {
+        0:    'IDLE',
+        0x10: 'ACTIVE',
+        0x11: 'RECORD',
+        0x12: 'START',
+        0x13: 'END',
+        0x14: 'ASM',
+        0x15: 'ERR',
+    }.get(int(J(L)['state']), 'INVALID')
+
 def tvisnumber(o):
     return itype(o) <= (0xfffeffff if LJ_64 and not LJ_GC64 else LJ_T['NUMX'])
 
@@ -239,7 +258,6 @@ def dump_lj_tfunc(tv):
 
     if ffid == 0:
         pt = funcproto(func)
-        # String will be printed with pointer to that string, thanks to gdb.
         return 'Lua function @ {addr}, {nupvals} upvalues, {chunk}:{line}'.format(
             addr = strx64(func),
             nupvals = int(func['nupvalues']),
@@ -262,7 +280,12 @@ def dump_lj_tcdata(tv):
     return 'cdata @ {}'.format(strx64(gcval(tv['gcr'])))
 
 def dump_lj_ttab(tv):
-    return 'table @ {}'.format(strx64(gcval(tv['gcr'])))
+    table = cast('GCtab *', gcval(tv['gcr']))
+    return 'table @ {gcr} (asize: {asize}, hmask: {hmask})'.format(
+        gcr = strx64(table),
+        asize = table['asize'],
+        hmask = strx64(table['hmask']),
+    )
 
 def dump_lj_tudata(tv):
     return 'userdata @ {}'.format(strx64(gcval(tv['gcr'])))
@@ -454,25 +477,32 @@ Dumps the contents of the GCtab at address.
         array = mref('TValue *', t['array'])
         nodes = mref('struct Node *', t['node'])
         mt = gcval(t['metatable'])
+        capacity = {
+            'apart': int(t['asize']),
+            'hpart': int(t['hmask'] + 1) if t['hmask'] > 0 else 0
+        }
 
         if mt != 0:
             gdb.write('Metatable detected: {}\n'.format(strx64(mt)))
 
-        gdb.write('Array part:\n')
-        for i in range(int(t['asize'])):
-            gdb.write('[{index}] {value}\n'.format(
+        gdb.write('Array part: {} slots\n'.format(capacity['apart']))
+        for i in range(capacity['apart']):
+            slot = array + i
+            gdb.write('{ptr}: [{index}]: {value}\n'.format(
+                ptr = slot,
                 index = i,
-                value = dump_tvalue(array + i)
+                value = dump_tvalue(slot)
             ))
 
-        gdb.write('Hash part:\n')
+        gdb.write('Hash part: {} nodes\n'.format(capacity['hpart']))
         # See hmask comment in lj_obj.h
-        for i in range(int(t['hmask'] + 1)):
+        for i in range(capacity['hpart']):
             node = nodes + i
-            gdb.write('{{ {key} }} => {{ {value} }} next = {next}\n'.format(
+            gdb.write('{ptr}: {{ {key} }} => {{ {val} }}; next = {n}\n'.format(
+                ptr = node,
                 key = dump_tvalue(node['key']),
-                value = dump_tvalue(node['val']),
-                next = mref('struct Node *', node['next'])
+                val= dump_tvalue(node['val']),
+                n = mref('struct Node *', node['next'])
             ))
 
 LJDumpTable()
@@ -505,7 +535,12 @@ Show current VM and GC state.
 
     def invoke(self, arg, from_tty):
         L = cast('lua_State *', parse_arg(arg))
-        gdb.write('VM state: {}\n'.format(vm_state(L)))
-        gdb.write('GC state: {}\n'.format(gc_state(L)))
+        gdb.write('{}\n'.format('\n'.join(
+            map(lambda t: '{} state: {}'.format(*t), {
+                'VM': vm_state(L),
+                'GC': gc_state(L),
+                'JIT': jit_state(L),
+            }.items())
+        )))
 
 LJState()
-- 
2.24.0



More information about the Tarantool-patches mailing list