From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id E0B976EFEC; Fri, 5 Jun 2026 17:55:18 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org E0B976EFEC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1780671319; bh=GKbw4qAiNyEG2/abRGCPG2cM93zjoZy4XWFLD985qRk=; h=Date:To:Cc:References:In-Reply-To:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Gi6MYByssnIy2JE6T7IVOrbIGgpL8nxUdXHrM4YyM3tT7ZLAyqkMV2nGA1ldWciOy 8hEBkvZDbYVqhX7i/LU8ziHuoPtbQVBrYrpiv7HBXoX8bUUrzSCqenr4qH2DqOhxYB sKN/hyf1qUSU3DencctgEEQEFZQ3hLeDxIhXavxU= Received: from send243.i.mail.ru (send243.i.mail.ru [95.163.59.82]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 55FB96EFEC for ; Fri, 5 Jun 2026 17:55:17 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 55FB96EFEC Received: by exim-smtp-85dd497b6-hfsjf with esmtpa (envelope-from ) id 1wVVx5-000000001vS-3sXA; Fri, 05 Jun 2026 17:55:16 +0300 Content-Type: multipart/alternative; boundary="------------Ka7xb54ak8iFS2JdO0VoWJIZ" Message-ID: <0396d6fa-a142-487c-b279-8cd6faa93b63@tarantool.org> Date: Fri, 5 Jun 2026 17:55:14 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: Sergey Kaplun , Evgeniy Temirgaleev Cc: tarantool-patches@dev.tarantool.org References: <20260604093052.2221827-1-skaplun@tarantool.org> In-Reply-To: <20260604093052.2221827-1-skaplun@tarantool.org> X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD9FAD06046D747065B904BF8DE1504AFD90984DF84FDFE86BA182A05F538085040A554C5575D4855853DE06ABAFEAF6705761F1078C4BF5282CF5BE8966240E96AAAA0C09783475C02 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE771540F9ECFC94C4BEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB5533756660A56BB7F6F20B60D6D8BD5B1B632539E76164E804A046623549EDA123ADA1F8389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C07E7E81EEA8A9722B8941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B652D31B9D28593E51CC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB86D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE74F0F518E68DBD4F843847C11F186F3C59DAA53EE0834AAEE X-C1DE0DAB: 0D63561A33F958A56F754B27B73990B35002B1117B3ED69648091DA0475E0D83B48B7A7F94616420823CB91A9FED034534781492E4B8EEAD2F8D89FC5850081EBDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0AD73CAD6646DEDE191716CD42B3DD1D34CAB70F9BE574AE9C625B6776AC983F447FC0B9F89525902EE6F57B2FD27647F25E66C117BDB76D6598C8C19FA40EB4C3BC0BEFBD220853A182BF6D36EAE240C1999EC28DEF0AA319DF2959F2F6C635316B8341EE9D5BE9A0A2AD1C5F3F15AC5C4B5F5A9E6EF0E0304EC0A19361DD1FE4B6536EB022892E5344C41F94D744909CE2512F26BEC029E55448553D2254B8D95CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVRI2994ruhLUr9IbLVTcuDo= X-DA7885C5: F7F060F739FEB2BEF255D290C0D534F9530CEADC1FAA3F0F53430D865DF9AEC6A08D079A7130C8E65B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F7393520AF17B8A65FDE2EF8FE86113D50160DE6FA200127E802E0EC1CCADCA64B485EF86D5F70DA33880E41E8EF7A07863ECB274557F927329BE2DDF8182D28ACDB545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit 0/4] Introduce dumpers for bytecodes in debuggers X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Bronnikov via Tarantool-patches Reply-To: Sergey Bronnikov Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" This is a multi-part message in MIME format. --------------Ka7xb54ak8iFS2JdO0VoWJIZ Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Hi, Sergey, thanks for your efforts in adding new functionality to dbg extension! On 6/4/26 12:30, Sergey Kaplun wrote: > Branch:https://github.com/tarantool/luajit/tree/skaplun/gh-4808-gco-func-proto-bytecode > Issue:https://github.com/tarantool/tarantool/issues/4808 > > This patch set allows you to inspect bytecodes for a single instruction, > as well as for all bytecodes inside a function or its prototype via GDB > and LLDB. > > The first patch is a fixup for the LLDB indexing negative values. It may > affect the lj-stack command. The second patch fixes the DUALNUM mode > detection in LLDB. These fixes are required for the last patch in the > series. > > The third auxiliary patch is needed to introduce dumpers for GC objects > similar to TValues dumpers. Also, it may be useful during different > debugging scenarios, so it introduces the lj-gco command to > dump the GC object info in the same format as for a TValue slot. > > The last patch introduces 3 new commands: > * lj-bc -- dump single bytecode instruction > * lj-func -- dump all bytecode instructions for Lua function > or report type of C or F function > * lj-proto -- dump all bytecode instructions for the > prototype > > For example, we have the following Lua script named : it is worth adding this example to the appropriate commit message. What do you think? > | 1 local function mywhile(a) > | 2 local r = 0 > | 3 print(a) > | 4 while (a < 30) do > | 5 r = r + a * r/2 > | 6 end > | 7 return r > | 8 end > | 9 > | 10 local uvname1 = false > | 11 local uvname2 = false > | 12 local function myif(a) > | 13 local s1 = a + 4 > | 14 local s2 = s1 + 4 > | 15 uvname1 = "s10" > | 16 uvname2 = "s11" > | 17 print(a) > | 18 if a > 10 then > | 19 return a + s2 + s1 > | 20 else > | 21 return a - 10 - s2 - s1 > | 22 end > | 23 end > | 24 > | 25 local f1 = myif > | 26 local f2 = mywhile > | 27 myif(12) > | 28 mywhile(12) > > Assume we set a breakpoint at `lj_cf_print` (line 3). > The lj-stack output contains the following lines: > > | 0x40001970 [ ] VALUE: Lua function @ 0x400083c0, 0 upvalues, "@../tmp.lua":1 > | 0x40001968 [ ] VALUE: Lua function @ 0x40002148, 2 upvalues, "@../tmp.lua":12 > | ... > | 0x40001940 [ ] FRAME: [V] delta=1, Lua function @ 0x400084a0, 0 upvalues, "@../tmp.lua":0 > > The first one is `myif()` function the second is `mywhile()` and the > last one is function loaded via `dofile()`. > > The resulting output for the functions is the following: > > 1) > | (gdb) lj-func 0x400083c0 > | "@../tmp.lua":1-8 > | 0000 FUNCF rbase: 4 > | 0001 KSHORT dst: 1 lits: 0 > | 0002 GGET dst: 2 str: 0 ; string "print" @ 0x400037f0 > | 0003 MOV dst: 3 var: 0 > | 0004 CALL base: 2 lit: 1 lit: 2 > | 0005 KSHORT dst: 2 lits: 30 > | 0006 ISGE var: 0 var: 2 > | 0007 JMP rbase: 2 jump: => 0013 > | 0008 LOOP rbase: 2 jump: => 0013 > | 0009 MULVV dst: 2 var: 0 var: 1 > | 0010 DIVVN dst: 2 var: 2 num: 0 ; number 2 > | 0011 ADDVV dst: 1 var: 1 var: 2 > | 0012 JMP rbase: 2 jump: => 0005 > | 0013 RET1 rbase: 1 lit: 2 > > The report is the same as for the following command: > | lj-proto (GCproto *)(((char *)(((GCfuncL *)0x400083c0)->pc.ptr32))-sizeof(GCproto)) > > 2) > | (gdb) lj-func 0x40002148 > | "@../tmp.lua":12-23 > | 0000 FUNCF rbase: 5 > | 0001 ADDVN dst: 1 var: 0 num: 0 ; number 4 > | 0002 ADDVN dst: 2 var: 1 num: 0 ; number 4 > | 0003 USETS uv: 0 str: 0 ; 0x40002527 "uvname1" ; string "s10" @ 0x40002298 > | 0004 USETS uv: 1 str: 1 ; 0x4000252f "uvname2" ; string "s11" @ 0x400022b8 > | 0005 GGET dst: 3 str: 2 ; string "print" @ 0x400037f0 > | 0006 MOV dst: 4 var: 0 > | 0007 CALL base: 3 lit: 1 lit: 2 > | 0008 KSHORT dst: 3 lits: 10 > | 0009 ISGE var: 3 var: 0 > | 0010 JMP rbase: 3 jump: => 0015 > | 0011 ADDVV dst: 3 var: 0 var: 2 > | 0012 ADDVV dst: 3 var: 3 var: 1 > | 0013 RET1 rbase: 3 lit: 2 > | 0014 JMP rbase: 3 jump: => 0019 > | 0015 SUBVN dst: 3 var: 0 num: 1 ; number 10 > | 0016 SUBVV dst: 3 var: 3 var: 2 > | 0017 SUBVV dst: 3 var: 3 var: 1 > | 0018 RET1 rbase: 3 lit: 2 > | 0019 RET0 rbase: 0 lit: 1 > > 3) > > | (gdb) lj-func 0x400084a0 > | "@../tmp.lua":0-30 > | 0000 FUNCV rbase: 8 > | 0001 FNEW dst: 0 func: 0 ; "@../tmp.lua":1 > | 0002 KPRI dst: 1 pri: 1 > | 0003 KPRI dst: 2 pri: 1 > | 0004 FNEW dst: 3 func: 1 ; "@../tmp.lua":12 > | 0005 MOV dst: 4 var: 3 > | 0006 MOV dst: 5 var: 0 > | 0007 MOV dst: 6 var: 3 > | 0008 KSHORT dst: 7 lits: 12 > | 0009 CALL base: 6 lit: 1 lit: 2 > | 0010 MOV dst: 6 var: 0 > | 0011 KSHORT dst: 7 lits: 12 > | 0012 CALL base: 6 lit: 1 lit: 2 > | 0013 UCLO rbase: 0 jump: => 0014 > | 0014 RET0 rbase: 0 lit: 1 > > The single bytecode instruction may be useful when you debug the VM: > > | (gdb) b lj_BC_ISGE > | Breakpoint 2 at 0x5555555f0a08 > | (gdb) c > | Continuing. > | Breakpoint 2, 0x00005555555f0a08 in lj_BC_ISGE () > | (gdb) lj-bc $rbx # PC refers __the next instruction__ > | JMP rbase: 3 jump: +5 > | (gdb) lj-bc ((BCIns *)$rbx) - 1 # current instruction > | ISGE var: 3 var: 0 > > > Sergey Kaplun (4): > dbg: fix lj-stack command for LLDB > dbg: fix DUALNUM detection for LLDB > dbg: introduce lj-gco command > dbg: introduce lj-bc, lj-func and lj-proto dumpers > > src/luajit_dbg.py | 650 ++++++++++++++++-- > .../debug-extension-tests.py | 203 +++++- > 2 files changed, 757 insertions(+), 96 deletions(-) > --------------Ka7xb54ak8iFS2JdO0VoWJIZ Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit

Hi, Sergey,

thanks for your efforts in adding new functionality to dbg extension!

On 6/4/26 12:30, Sergey Kaplun wrote:
Branch: https://github.com/tarantool/luajit/tree/skaplun/gh-4808-gco-func-proto-bytecode
Issue: https://github.com/tarantool/tarantool/issues/4808

This patch set allows you to inspect bytecodes for a single instruction,
as well as for all bytecodes inside a function or its prototype via GDB
and LLDB.

The first patch is a fixup for the LLDB indexing negative values. It may
affect the lj-stack command. The second patch fixes the DUALNUM mode
detection in LLDB. These fixes are required for the last patch in the
series.

The third auxiliary patch is needed to introduce dumpers for GC objects
similar to TValues dumpers. Also, it may be useful during different
debugging scenarios, so it introduces the lj-gco <GCobj *> command to
dump the GC object info in the same format as for a TValue slot.

The last patch introduces 3 new commands:
* lj-bc <GCIns *> -- dump single bytecode instruction
* lj-func <GCfunc *> -- dump all bytecode instructions for Lua function
  or report type of C or F function
* lj-proto <GCproto *> -- dump all bytecode instructions for the
  prototype

For example, we have the following Lua script named <tmp.lua>:
it is worth adding this example to the appropriate commit message. What do you think?
| 1 local function mywhile(a)
| 2 	local r = 0
| 3 	print(a)
| 4 	while (a < 30) do
| 5 		r = r + a * r/2
| 6 	end
| 7 	return r
| 8 end
| 9
| 10 local uvname1 = false
| 11 local uvname2 = false
| 12 local function myif(a)
| 13 	local s1 = a + 4
| 14 	local s2 = s1 + 4
| 15 	uvname1 = "s10"
| 16 	uvname2 = "s11"
| 17 	print(a)
| 18 	if a > 10 then
| 19 		return a + s2 + s1
| 20 	else
| 21 		return a - 10 - s2 - s1
| 22 	end
| 23 end
| 24
| 25 local f1 = myif
| 26 local f2 = mywhile
| 27 myif(12)
| 28 mywhile(12)

Assume we set a breakpoint at `lj_cf_print` (line 3).
The lj-stack output contains the following lines:

| 0x40001970            [    ] VALUE: Lua function @ 0x400083c0, 0 upvalues, "@../tmp.lua":1
| 0x40001968            [    ] VALUE: Lua function @ 0x40002148, 2 upvalues, "@../tmp.lua":12
| ...
| 0x40001940            [    ] FRAME: [V] delta=1, Lua function @ 0x400084a0, 0 upvalues, "@../tmp.lua":0

The first one is `myif()` function the second is `mywhile()` and the
last one is function loaded via `dofile()`.

The resulting output for the functions is the following:

1)
| (gdb) lj-func 0x400083c0
| "@../tmp.lua":1-8
| 0000 FUNCF  rbase:   4
| 0001 KSHORT dst:     1 lits:    0
| 0002 GGET   dst:     2 str:     0 ; string "print" @ 0x400037f0
| 0003 MOV    dst:     3 var:     0
| 0004 CALL   base:    2 lit:     1 lit:     2
| 0005 KSHORT dst:     2 lits:   30
| 0006 ISGE   var:     0 var:     2
| 0007 JMP    rbase:   2 jump:  => 0013
| 0008 LOOP   rbase:   2 jump:  => 0013
| 0009 MULVV  dst:     2 var:     0 var:     1
| 0010 DIVVN  dst:     2 var:     2 num:     0 ; number 2
| 0011 ADDVV  dst:     1 var:     1 var:     2
| 0012 JMP    rbase:   2 jump:  => 0005
| 0013 RET1   rbase:   1 lit:     2

The report is the same as for the following command:
| lj-proto (GCproto *)(((char *)(((GCfuncL *)0x400083c0)->pc.ptr32))-sizeof(GCproto))

2)
| (gdb) lj-func 0x40002148
| "@../tmp.lua":12-23
| 0000 FUNCF  rbase:   5
| 0001 ADDVN  dst:     1 var:     0 num:     0 ; number 4
| 0002 ADDVN  dst:     2 var:     1 num:     0 ; number 4
| 0003 USETS  uv:      0 str:     0 ; 0x40002527 "uvname1" ; string "s10" @ 0x40002298
| 0004 USETS  uv:      1 str:     1 ; 0x4000252f "uvname2" ; string "s11" @ 0x400022b8
| 0005 GGET   dst:     3 str:     2 ; string "print" @ 0x400037f0
| 0006 MOV    dst:     4 var:     0
| 0007 CALL   base:    3 lit:     1 lit:     2
| 0008 KSHORT dst:     3 lits:   10
| 0009 ISGE   var:     3 var:     0
| 0010 JMP    rbase:   3 jump:  => 0015
| 0011 ADDVV  dst:     3 var:     0 var:     2
| 0012 ADDVV  dst:     3 var:     3 var:     1
| 0013 RET1   rbase:   3 lit:     2
| 0014 JMP    rbase:   3 jump:  => 0019
| 0015 SUBVN  dst:     3 var:     0 num:     1 ; number 10
| 0016 SUBVV  dst:     3 var:     3 var:     2
| 0017 SUBVV  dst:     3 var:     3 var:     1
| 0018 RET1   rbase:   3 lit:     2
| 0019 RET0   rbase:   0 lit:     1

3)

| (gdb) lj-func 0x400084a0
| "@../tmp.lua":0-30
| 0000 FUNCV  rbase:   8
| 0001 FNEW   dst:     0 func:    0 ; "@../tmp.lua":1
| 0002 KPRI   dst:     1 pri:     1
| 0003 KPRI   dst:     2 pri:     1
| 0004 FNEW   dst:     3 func:    1 ; "@../tmp.lua":12
| 0005 MOV    dst:     4 var:     3
| 0006 MOV    dst:     5 var:     0
| 0007 MOV    dst:     6 var:     3
| 0008 KSHORT dst:     7 lits:   12
| 0009 CALL   base:    6 lit:     1 lit:     2
| 0010 MOV    dst:     6 var:     0
| 0011 KSHORT dst:     7 lits:   12
| 0012 CALL   base:    6 lit:     1 lit:     2
| 0013 UCLO   rbase:   0 jump:  => 0014
| 0014 RET0   rbase:   0 lit:     1

The single bytecode instruction may be useful when you debug the VM:

| (gdb) b lj_BC_ISGE
| Breakpoint 2 at 0x5555555f0a08
| (gdb) c
| Continuing.
| Breakpoint 2, 0x00005555555f0a08 in lj_BC_ISGE ()
| (gdb) lj-bc $rbx # PC refers __the next instruction__
| JMP    rbase:   3 jump:  +5
| (gdb) lj-bc ((BCIns *)$rbx) - 1 # current instruction
| ISGE   var:     3 var:     0


Sergey Kaplun (4):
  dbg: fix lj-stack command for LLDB
  dbg: fix DUALNUM detection for LLDB
  dbg: introduce lj-gco command
  dbg: introduce lj-bc, lj-func and lj-proto dumpers

 src/luajit_dbg.py                             | 650 ++++++++++++++++--
 .../debug-extension-tests.py                  | 203 +++++-
 2 files changed, 757 insertions(+), 96 deletions(-)

--------------Ka7xb54ak8iFS2JdO0VoWJIZ--