From: Sergey Kaplun via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: Sergey Bronnikov <sergeyb@tarantool.org>
Cc: tarantool-patches@dev.tarantool.org
Subject: Re: [Tarantool-patches] [PATCH luajit 1/3] dbg: introduce lj-ir, lj-jslots, lj-trace dumpers
Date: Tue, 30 Jun 2026 19:01:51 +0300 [thread overview]
Message-ID: <akPobzlZL-LzrBNC@root> (raw)
In-Reply-To: <74882449-a4cc-4602-a8b3-75bd5e9724eb@tarantool.org>
Hi, Sergey!
Thanks for the review!
Fixed your comments and force-pushed the branch.
On 30.06.26, Sergey Bronnikov wrote:
> Hi, Sergey,
>
> thanks for the patch! LGTM with minor comments.
>
> Sergey
>
> On 6/25/26 23:29, Sergey Kaplun wrote:
> > This patch adds dumpers for a single IR instruction (`lj-ir`), as well
> > as for all bytecodes inside one trace (`lj-trace`). Its dump is quite
> > similar to the -jdump flag but also reports types of register operands
> > (`ref`, `lit`, `cst`) and operation mode (`N`, `A`, `W`, etc.).
> > The `lj-trace` command accepts optional /rs flags to dump registers
> > associated with IR and snapshots for the trace correspondingly.
> > The `lj-ir` command can be used for dumping IR constants as well.
> > The `lj-jslots` command dumps the content of `J->slot`. It is useful to
> > simplify debugging of `rec_check_slots()` assertion failures.
> >
> > For LLDB value, the `__getitem__` metamethod now accepts bool keys.
> > Also, `__index__` is set to allow lldb.value to be used as an index
> > without explicit conversion to int. Old GDB versions (below 7.12) are
> > not supported because of the gdb.Value lacks the `__index__` metamethod
> > and can't be monkey-patched. The support for these versions may be added
> > by demand.
> >
> > Part of tarantool/tarantool#4808
> > ---
> > src/luajit_dbg.py | 1216 ++++++++++++++++-
> > .../debug-extension-tests.py | 365 +++++
> > 2 files changed, 1570 insertions(+), 11 deletions(-)
> >
> > diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
> > index 2edb199a..fd6ca8a5 100644
> > --- a/src/luajit_dbg.py
> > +++ b/src/luajit_dbg.py
> > @@ -58,6 +58,26 @@ class Debugger(object):
> > self.LLDB = True
> > return super(Debugger, self).__new__(_LLDBDebugger)
> >
> > + def parse_flags(self, raw_flags, permitted_flags):
> > + flags = {}
> > + for flag in raw_flags:
> > + if flag not in permitted_flags:
> > + raise self.error('Unrecongnized option: "{}"'.format(flag))
> typo: s/Unrecongnized/Unrecognized/
Fixed, thanks!
===================================================================
diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
index 19cefaed..6412575c 100644
--- a/src/luajit_dbg.py
+++ b/src/luajit_dbg.py
@@ -62,7 +62,7 @@ class Debugger(object):
flags = {}
for flag in raw_flags:
if flag not in permitted_flags:
- raise self.error('Unrecongnized option: "{}"'.format(flag))
+ raise self.error('Unrecognized option: "{}"'.format(flag))
flags[flag] = True
return flags
===================================================================
> > + flags[flag] = True
> > + return flags
> > +
<snipped>
> > + def member_by_offset(self, tp, offset, prev_name=None):
> > + if isinstance(tp, str):
> > + tp = self._dbgtype(tp)
> > + assert offset < tp.sizeof, 'offset is bigger than object size'
> > + if tp.code == gdb.TYPE_CODE_TYPEDEF:
> > + tp = tp.strip_typedefs()
> > + if tp.code == gdb.TYPE_CODE_STRUCT:
> > + fields = tp.fields()
> > + for n_field in range(len(fields)):
> > + islast = n_field == (len(fields) - 1)
> > + field = fields[n_field]
> > + start_field = field.bitpos / 8
> may be //?
I'm not sure that this is crucial. In case when the bitpos isn't a
multiple of 8 we will get an error, so we may find the bug earlier
instead of an incorrect result. I'd prefer to ignore it if you don't
insist.
> > + end_field = fields[n_field + 1].bitpos / 8 if not islast \
> > + else tp.sizeof
> > + if start_field <= offset and offset < end_field:
> > + next_name = self.member_by_offset(
> > + field.type,
> > + offset - start_field,
> > + prev_name=field.name
> > + )
> > + return '.{field}{suffix}'.format(
> > + field=field.name,
> > + suffix=next_name if next_name else ''
> > + )
<snipped>
> > @@ -322,8 +428,26 @@ class _LLDBDebugger(Debugger):
> > def lldb__getitem__(lldbval, key):
> > if type(key) is lldb.value:
> > key = int(key)
> > + if type(key) is bool:
> > + key = int(key)
> > if type(key) is int:
> > # Allow array access.
> > + ltp = lldbval.sbvalue.GetType()
> > + # XXX: LLDB in versions 17 - 19 can't use an array
> > + # object as the initializer for `lldb.value` since
> > + # `GetValue()` for it returns `None` leading to
> > + # the invalid result. See
> > + #https://github.com/llvm/llvm-project/pull/90144.
> > + if (self.version < 17 or self.version > 19) or \
> > + ltp.GetTypeClass() != lldb.eTypeClassArray:
> > + pass
> probably it is better to invert condition and remove section with "pass"
The same condition is used for loading the global symbol, so it is more
bulletproof, I suppose. Also, this attracts an attention about the
mentioned issue. I'd prefer to leave it as is if you don't insist.
> > +
> > +
> > +def ir_kptr(ir):
> > + irname = IRS[ir['o']]
> > + assert irname == 'KPTR' or irname == 'KKPTR', 'wrong IR for ir_iptr()'
> typo: s/ir_iptr()/ir_kptr() or ir_kkptr()/
Fixed, thanks:
===================================================================
diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
index 6412575c..d5967716 100644
--- a/src/luajit_dbg.py
+++ b/src/luajit_dbg.py
@@ -2001,7 +2001,7 @@ def irt_toitype(irt):
def ir_kptr(ir):
irname = IRS[ir['o']]
- assert irname == 'KPTR' or irname == 'KKPTR', 'wrong IR for ir_iptr()'
+ assert irname == 'KPTR' or irname == 'KKPTR', 'wrong IR for ir_kptr()'
return mref('void *', dbg.cast('IRIns *', dbg.address(ir))[LJ_GC64]['ptr'])
===================================================================
> > + return mref('void *', dbg.cast('IRIns *', dbg.address(ir))[LJ_GC64]['ptr'])
<snipped>
> > +def ir_kint64(ir):
> > + irname = IRS[ir['o']]
> > + assert irname == 'KINT64', 'wrong IR for ir_knum()'
> typo: s/ir_knum/ir_kint64/
Fixed, thanks:
===================================================================
diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
index d5967716..68f7970b 100644
--- a/src/luajit_dbg.py
+++ b/src/luajit_dbg.py
@@ -2019,7 +2019,7 @@ def ir_knum(ir):
def ir_kint64(ir):
irname = IRS[ir['o']]
- assert irname == 'KINT64', 'wrong IR for ir_knum()'
+ assert irname == 'KINT64', 'wrong IR for ir_kint64()'
return dbg.address(dbg.cast('IRIns *', dbg.address(ir))[1]['tv'])
===================================================================
<snipped>
> > + for slot in range(0, snap['nslots']):
> > + dump += ' '
> > + snap_entry = int(snap_map[snap_entry_num])
> > + if snap_entry_num < snap['nent'] and snap_entry >> TREF_SHIFT == slot:
> > + snap_entry_num += 1
> > + ref = int((snap_entry & TREF_REFMASK) - REF_BIAS)
> > + if ref < 0:
> > + if int(snap_entry) == 0x1057fff:
> magic number
Indeed, fixed:
===================================================================
diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
index 68f7970b..9534dfad 100644
--- a/src/luajit_dbg.py
+++ b/src/luajit_dbg.py
@@ -1956,6 +1956,7 @@ RID_SUNK = (RID_INIT - 2)
SPS_NONE = 0
REF_BIAS = 0x8000
+REF_NIL = REF_BIAS - 1
TREF_SHIFT = 24
@@ -1964,8 +1965,11 @@ TREF_FRAME = 0x00010000
TREF_CONT = 0x00020000
# Snapshot flags and masks.
SNAP_FRAME = 0x010000
+SNAP_NORESTORE = 0x040000
SNAP_SOFTFPNUM = 0x080000
+SNAP_FR2_SLOT = (1 << TREF_SHIFT) | SNAP_FRAME | SNAP_NORESTORE + REF_NIL
+
def irt_type(t):
return dbg.cast('IRType', t['irt'] & IRT_TYPE)
@@ -2810,7 +2813,7 @@ def dump_snap(trace, snapno, snap):
snap_entry_num += 1
ref = int((snap_entry & TREF_REFMASK) - REF_BIAS)
if ref < 0:
- if int(snap_entry) == 0x1057fff:
+ if int(snap_entry) == SNAP_FR2_SLOT:
dump += '----'
continue
elif (snap_entry & TREF_CONT):
===================================================================
> <snipped>
> > +# Assume not cross-platform debugging.
> > +machine = os.uname().machine
> > +if machine == 'x86_64':
> > + RX_GPR = r'r\w\w'
> > + RX_FPR = r'xmm\d+'
> > +elif machine == 'arm64' or machine == 'aarch64':
> > + RX_GPR = r'x\d+'
> > + RX_FPR = r'd\d+'
> > +else:
> > + raise Exception('Unknown archeticture in testing')
> typo: s/archeticture/architecture/
Fixed, thanks!
===================================================================
diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py
index 71b763d2..895171a4 100644
--- a/test/tarantool-debugger-tests/debug-extension-tests.py
+++ b/test/tarantool-debugger-tests/debug-extension-tests.py
@@ -124,7 +124,7 @@ elif machine == 'arm64' or machine == 'aarch64':
RX_GPR = r'x\d+'
RX_FPR = r'd\d+'
else:
- raise Exception('Unknown archeticture in testing')
+ raise Exception('Unknown architecture in testing')
class TestCaseBase(unittest.TestCase):
===================================================================
> <snipped>
> > +
> > +class TestLJIRConst(TestCaseBase):
> > + location = 'trace_stop'
> > +
> > + # No narrowing of 42.
> > + if IS_DUALNUM:
> > + # KNUM occupies 2 slots.
> > + _knum_irnum = '6'
> > + _kgc_irnum = '8' if IS_GC64 else '7'
> > + _kptr_irnum = '10' if IS_GC64 else '8'
> > + else:
> > + # KNUM occupies 2 slots.
> > + _knum_irnum = '8'
> > + _kgc_irnum = '10' if IS_GC64 else '9'
> > + _kptr_irnum = '12' if IS_GC64 else '10'
> both branches contains the same comment, is it a typo or not?
It is intentional. KNUM occupies 2 slots anyway.
> > <snipped>
> >
--
Best regards,
Sergey Kaplun
next prev parent reply other threads:[~2026-06-30 16:02 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-25 20:29 [Tarantool-patches] [PATCH luajit 0/3] Extend debug extension Sergey Kaplun via Tarantool-patches
2026-06-25 20:29 ` [Tarantool-patches] [PATCH luajit 1/3] dbg: introduce lj-ir, lj-jslots, lj-trace dumpers Sergey Kaplun via Tarantool-patches
2026-06-28 1:03 ` Evgeniy Temirgaleev via Tarantool-patches
2026-06-28 16:32 ` Sergey Kaplun via Tarantool-patches
2026-06-29 16:35 ` Evgeniy Temirgaleev via Tarantool-patches
2026-06-30 14:45 ` Sergey Bronnikov via Tarantool-patches
2026-06-30 16:01 ` Sergey Kaplun via Tarantool-patches [this message]
2026-07-01 11:23 ` Sergey Bronnikov via Tarantool-patches
2026-06-25 20:29 ` [Tarantool-patches] [PATCH luajit 2/3] dbg: introduce lj-ctype command, extend cdata dump Sergey Kaplun via Tarantool-patches
2026-06-29 13:55 ` Evgeniy Temirgaleev via Tarantool-patches
2026-06-29 19:20 ` Sergey Kaplun via Tarantool-patches
2026-06-30 11:48 ` Evgeniy Temirgaleev via Tarantool-patches
2026-06-30 12:27 ` Sergey Kaplun via Tarantool-patches
2026-06-30 13:07 ` Evgeniy Temirgaleev via Tarantool-patches
2026-06-30 14:03 ` Sergey Kaplun via Tarantool-patches
2026-06-30 15:07 ` Evgeniy Temirgaleev via Tarantool-patches
2026-06-30 14:53 ` Sergey Bronnikov via Tarantool-patches
2026-06-30 15:03 ` Sergey Kaplun via Tarantool-patches
2026-07-01 8:25 ` Sergey Kaplun via Tarantool-patches
2026-07-01 11:20 ` Sergey Bronnikov via Tarantool-patches
2026-06-25 20:29 ` [Tarantool-patches] [PATCH luajit 3/3] test: add verbose mode for debug extension tests Sergey Kaplun via Tarantool-patches
2026-06-28 1:31 ` Evgeniy Temirgaleev via Tarantool-patches
2026-06-28 15:19 ` Sergey Kaplun via Tarantool-patches
2026-06-30 14:54 ` Sergey Bronnikov 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=akPobzlZL-LzrBNC@root \
--to=tarantool-patches@dev.tarantool.org \
--cc=sergeyb@tarantool.org \
--cc=skaplun@tarantool.org \
--subject='Re: [Tarantool-patches] [PATCH luajit 1/3] dbg: introduce lj-ir, lj-jslots, lj-trace dumpers' \
/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