<HTML><BODY><div class="cl-x3x6ve7ye3"><div>Hi, Sergey!</div><div> </div><div>LGTM. And please see my note about renaming issue.</div><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><span>From: Sergey Kaplun <<a href="mailto:skaplun@tarantool.org">skaplun@tarantool.org</a>><br>To: Evgeniy Temirgaleev <<a href="mailto:e.temirgaleev@tarantool.org">e.temirgaleev@tarantool.org</a>><br>Cc: tarantool-patches@dev.tarantool.org, Sergey Bronnikov <<a href="mailto:sergeyb@tarantool.org">sergeyb@tarantool.org</a>><br>Date: Monday, June 29, 2026 10:21 PM +03:00</span><br> <div><div id=""><div class="cl-9pa0x03zuw"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div id="style_17827608680724976795_mr_css_attr"><div id="style_17827608680724976795_BODY_mr_css_attr">Hi, Evgeniy!<br>Thanks for the review!<br>Fixed your comments and force-pushed the branch.<br><br>On 29.06.26, Evgeniy Temirgaleev wrote:<br>> Hi, Sergey!<br>><br>> Thanks for the patch!<br>> Please, see the commends below.<br>><br>> --<br>> Best regards,<br>> Evgeniy Temirgaleev<br>><br>> ><br>> > From: Sergey Kaplun <<a href="mailto:skaplun@tarantool.org">skaplun@tarantool.org</a>><br>> > To: Sergey Bronnikov <<a href="mailto:sergeyb@tarantool.org">sergeyb@tarantool.org</a>>, Evgeniy Temirgaleev <<a href="mailto:e.temirgaleev@tarantool.org">e.temirgaleev@tarantool.org</a><br>> > ><br>> > Cc: tarantool-patches@dev.tarantool.org, Sergey Kaplun <<a href="mailto:skaplun@tarantool.org">skaplun@tarantool.org</a><br>> > ><br>> > Date: Thursday, June 25, 2026 11:29 PM +03:00<br>> > This patch extends dumped information for the given cdata object. Now<br>> > it resolves the given `CType` and prints it in the format similar to the<br>> > `__tostring` metamethod. The `lj-ctype` command is introduced to dump<br>> > this information where there is only the `CType` pointer but no cdata<br>> > associated with it.<br>> ><br>> > `__or__` and `__ror__` metamethods are monkey-patched for the LLDB value<br>> > object. In `__sub__` metamethod for LLDB pointers `GetPointeeType()` is<br>> > used to get the pointee type instead of the incorrectly used<br>> > `GetDereferencedType()` which always returns the same type with size 8.<br>> > Casting from negative values to the unsigned values is supported to<br>> > check `CTF_UCHAR`.<br>> ><br>> > Part of tarantool/tarantool#4808<br>> > ---<br>> > src/luajit_dbg.py | 333 +++++++++++++++++-<br>> > .../debug-extension-tests.py | 208 ++++++++++-<br>> > 2 files changed, 535 insertions(+), 6 deletions(-)<br>> ><br>> > diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py<br>> > index fd6ca8a5..62cd65d5 100644<br>> > --- a/src/luajit_dbg.py<br>> > +++ b/src/luajit_dbg.py<br>> > @@ -386,6 +386,8 @@ class _LLDBDebugger(Debugger):<br>> > pack_flag = '<q'<br>> > else:<br>> > pack_flag = '<Q'<br>> > + # Cast to unsigned.<br>> ><br>><br>> Is /unsigned/uint64_t/ clearly?<br><br>Rephrased as you suggested. Also, lowercase the value to be consistent<br>with other hexademical values.</div></div></div></div></div></div></blockquote></div></div><div>Thanks!</div><div class="cl-x3x6ve7ye3"><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-9pa0x03zuw"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div><br>===================================================================<br>diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py<br>index 6b0827d9..0769f2ee 100644<br>--- a/src/luajit_dbg.py<br>+++ b/src/luajit_dbg.py<br>@@ -386,8 +386,8 @@ class _LLDBDebugger(Debugger):<br>pack_flag = '<q'<br>else:<br>pack_flag = '<Q'<br>- # Cast to unsigned.<br>- raw_value &= 0xFFFFFFFFFFFFFFFF<br>+ # Cast to 64-bit unsigned value in Python.<br>+ raw_value &= 0xffffffffffffffff<br>raw_data = struct.pack(pack_flag, raw_value)<br>sbdata = lldb.SBData()<br>sbdata.SetData(<br>===================================================================<br><br>><br>> ><br>> > + raw_value &= 0xFFFFFFFFFFFFFFFF<br>> > raw_data = struct.pack(pack_flag, raw_value)<br>> > sbdata = lldb.SBData()<br>> > sbdata.SetData(<br><br><snipped><br><br>> > +<br>> > +<br>> > +def ctinfo(ct, flags):<br>> ><br>><br>> May we name this function ‘CTINFO’ as in ‘lj_ctype.h’? Or leave a comment with an original name for quick grep.<br><br>Added a comment since the upper case is used for constants.</div></div></div></div></div></div></blockquote></div></div><div>Thanks!</div><div class="cl-x3x6ve7ye3"><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-9pa0x03zuw"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div><br>===================================================================<br>diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py<br>index 0769f2ee..de83a2b5 100644<br>--- a/src/luajit_dbg.py<br>+++ b/src/luajit_dbg.py<br>@@ -1427,6 +1427,7 @@ def ctype_attrib(info):<br>return (info >> CTSHIFT_ATTRIB) & CTMASK_ATTRIB<br><br><br>+# Implementation of the `CTINFO()` macro.<br>def ctinfo(ct, flags):<br>return (tou32(ct) << CTSHIFT_NUM) + flags<br><br>===================================================================<br><br><br>><br>> ><br>> > + return (tou32(ct) << CTSHIFT_NUM) + flags<br>> > +<br>> > +<br>> > +def ctype_isptr(info):<br>> > + return ctype_type(info) == CT_PTR<br>> > +<br>> > +<br>> > +def ctype_iscomplex(info):<br>> > + return (info & (CTMASK_NUM | CTF_COMPLEX)) == ctinfo(CT_ARRAY,<br>> > CTF_COMPLEX)<br>> > +<br>> > +<br>> > +def ctype_isinteger(info):<br>> > + return (info & (CTMASK_NUM | CTF_BOOL | CTF_FP)) == ctinfo(CT_NUM, 0)<br>> > +<br>> > +<br>> > +def ctype_isrefarray(info):<br>> > + return (info & (CTMASK_NUM | CTF_VECTOR | CTF_COMPLEX)) == \<br>> > + ctinfo(CT_ARRAY, 0)<br>> > +<br>> > +<br>> > +def ctype_cid(info):<br>> ><br>><br>> Let’s put these function definitions in the ‘lj_ctype.h’ order?<br>> May we group the definitions by corresponding C files also? # lj_ctype.h … # lj_cdata.h … # lj_xxx.c …<br><br><br>Sorted as you suggested. The sorting is the following:<br>* lj_ctype.h<br>* lj_cdata.h -- `cdata_getptr()`<br>* lj_obj.h -- `cdataptr()`</div></div></div></div></div></div></blockquote></div></div><div>Thanks! We can add a comment with file name before each block to improve readability slightly more. Feel free to ignore.</div><div class="cl-x3x6ve7ye3"><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-9pa0x03zuw"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div> </div></div></div></div></div></div></blockquote></div></div><div><snipped></div><div class="cl-x3x6ve7ye3"><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-9pa0x03zuw"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div><br>><br>> ><br>> > + return info & CTMASK_CID<br>> > +<br>> > +<br>> > +def ctype_child(cts, ctype):<br>> > + return ctype_get(cts, ctype_cid(ctype['info']))<br>> > +<br>> > +<br>> > +def cdataptr(cd):<br>> > + return dbg.cast('void *', (cd + 1))<br>> > +<br>> > +<br>> > +def cdata_getptr(p, size):<br>> > + if LJ_64 and size == 4:<br>> > + return dbg.cast('void *', dbg.cast('uint32_t *', p)[0])<br>> > + else:<br>> ><br>><br>> assert for size == 8 ?<br><br>Added since it may possibly lead to the incorrect (shrinked) pointer<br>result. If we ever see the 16-bit pointers. Also, support the 32-bit<br>systems (not LJ_64) as well.</div></div></div></div></div></div></blockquote></div></div><div>Thanks!</div><div class="cl-x3x6ve7ye3"><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-9pa0x03zuw"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div><br>================================================================<br>diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py<br>index 183dda3b..de22d450 100644<br>--- a/src/luajit_dbg.py<br>+++ b/src/luajit_dbg.py<br>@@ -1463,9 +1463,10 @@ def ctype_typeid(cts, ct):<br><br><br>def cdata_getptr(p, size):<br>- if LJ_64 and size == 4:<br>+ if (LJ_64 and size == 4) or not LJ_64:<br>return dbg.cast('void *', dbg.cast('uint32_t *', p)[0])<br>else:<br>+ assert size == 8, 'incorrect pointer size'<br>return dbg.cast('void *', dbg.cast('uint64_t *', p)[0])<br><br><br>================================================================<br><br>><br>> ><br>> > + return dbg.cast('void *', dbg.cast('uint64_t *', p)[0])<br>> > +<br>> > +<br><br><snipped><br><br>> > +def ctype_prepnum(ctypestr, info, size):<br>> ><br>><br>> Func proto differs with lj_ctype.c (static void ctype_prepnum(CTRepr *ctr, uint32_t n)).<br>> It seems, you move some of ctype_repr() code here. Let’s comment it?<br><br>===================================================================<br>diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py<br>index de22d450..28cbe97d 100644<br>--- a/src/luajit_dbg.py<br>+++ b/src/luajit_dbg.py<br>@@ -2479,6 +2479,8 @@ def ctype_preptype(cts, ctypestr, ctype, qual, tp):<br>return ctypestr<br><br><br>+# Partially moved the code from `ctype_repr()` here to make it<br>+# more readable.<br>def ctype_prepnum(ctypestr, info, size):<br>if info & CTF_BOOL:<br>ctypestr = ctype_preplit(ctypestr, 'bool')<br>===================================================================</div></div></div></div></div></div></blockquote></div></div><div>Thanks!</div><div class="cl-x3x6ve7ye3"><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-9pa0x03zuw"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div><br><snipped><br><br>> > +def dump_ctype(ct):<br>> ><br>><br>> Also, it seems, it will be easy to read to code, if it will be possible to distinguish between ported functions and extension itself ones. May be by use the ‘dbg_’ prefix for extension function names.<br><br>I suppose this refactoring can be done in the separate issue. Since it<br>is related to all functions. Also, the `dbg` is already used for the<br>instance of the corresponding class. `dump_` prefix looks common for all<br>dumpers of our extension.</div></div></div></div></div></div></blockquote></div></div><div>Agreed. And I vote for this patch.</div><div>May be it will be several documented prefixes. It will be more verbosely, but I think it will be very helpful in a long perspective for supporting the extension to quick distinguish LuaJIT-ported routine e.g. `ctype_preplit` with extension routine e.g. `cdata_val_int64`.</div><div>Can you offer some prefix name good for you now? May be we can start naming with it at this point, what do you think?</div><div class="cl-x3x6ve7ye3"><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-9pa0x03zuw"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div><br><br><skipped><br><br>> > +class TestLJCTypeBase(TestCaseBase):<br>> > + location = 'lj_cf_ffi_new'<br>> > + extension_cmds = (<br>> > + # Load `ct`. Skip inlined functions for LLDB.<br>> ><br>><br>> The extension command set is common for GDB and LLDB. Does we skip for GDB also?<br><br>For GDB this function isn't inlined, but these n-s are harmless.<br>Adjusted the comment.</div></div></div></div></div></div></blockquote></div></div><div>Thanks!</div><div class="cl-x3x6ve7ye3"><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-9pa0x03zuw"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div><br>===================================================================<br>diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py<br>index f17de27e..71b763d2 100644<br>--- a/test/tarantool-debugger-tests/debug-extension-tests.py<br>+++ b/test/tarantool-debugger-tests/debug-extension-tests.py<br>@@ -1033,7 +1033,9 @@ class TestLJCTypeFunc(TestCaseBase):<br>class TestLJCTypeBase(TestCaseBase):<br>location = 'lj_cf_ffi_new'<br>extension_cmds = (<br>- # Load `ct`. Skip inlined functions for LLDB.<br>+ # Load `ct`. Skip inlined functions for LLDB. The skip is<br>+ # harmless for GDB since we are still in the body of the<br>+ # function.<br>'n\n'<br>'n\n'<br>'n\n'<br>===================================================================<br><br><br>><br>> ><br>> > + 'n\n'<br>> > + 'n\n'<br>> > + 'n\n'<br>> > + 'n\n'<br>> > + 'n\n'<br>> > + 'n\n'<br>> > + 'lj-ctype ct\n'<br>> > + )<br><br><snipped><br><br>> > --<br>> > 2.54.0<br>> ><br><br>--<br>Best regards,<br>Sergey Kaplun</div></div></div></div></div></div></blockquote></div></div><div><div>--<br>Best regards,</div><div>Evgeniy Temirgaleev</div></div></BODY></HTML>