Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH luajit] dbg: remove wrong GC state
@ 2026-10-15  7:20 Mikhail Elhimov via Tarantool-patches
  2026-10-15 23:45 ` [Tarantool-patches] [PATCH luajit v2] " Mikhail Elhimov via Tarantool-patches
  0 siblings, 1 reply; 6+ messages in thread
From: Mikhail Elhimov via Tarantool-patches @ 2026-10-15  7:20 UTC (permalink / raw)
  To: Sergey Kaplun, Sergey Bronnikov, Evgeniy Temirgaleev; +Cc: tarantool-patches

It was copied originally by mistake from the LuaVela fork of LuaJIT.
---
Branch: https://github.com/tarantool/luajit/tree/elhimov/gh-noticket-dbg-remove-wrong-gcstate

 src/luajit_dbg.py                             |  3 +-
 .../debug-extension-tests.py                  | 96 +++++++++++++++++--
 2 files changed, 87 insertions(+), 12 deletions(-)

diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
index 1d553fb9..4ee2e70e 100644
--- a/src/luajit_dbg.py
+++ b/src/luajit_dbg.py
@@ -1246,7 +1246,6 @@ def gc_state(g):
         3: 'SWEEPSTRING',
         4: 'SWEEP',
         5: 'FINALIZE',
-        6: 'LAST',
     }.get(int(g['gc']['state']), 'INVALID')
 
 
@@ -2841,7 +2840,7 @@ class LJState(dbg.LJBase):
 lj-state
 The command requires no args and dumps current VM and GC states:
 * VM state: <INTERP|C|GC|EXIT|RECORD|OPT|ASM|TRACE>
-* GC state: <PAUSE|PROPAGATE|ATOMIC|SWEEPSTRING|SWEEP|FINALIZE|LAST>
+* GC state: <PAUSE|PROPAGATE|ATOMIC|SWEEPSTRING|SWEEP|FINALIZE>
 * JIT state: <IDLE|ACTIVE|RECORD|START|END|ASM|ERR>
     '''
 
diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py
index b6e51185..8456dde9 100644
--- a/test/tarantool-debugger-tests/debug-extension-tests.py
+++ b/test/tarantool-debugger-tests/debug-extension-tests.py
@@ -133,6 +133,23 @@ elif machine == 'arm64' or machine == 'aarch64':
 else:
     raise Exception('Unknown architecture in testing')
 
+GCS_PAUSE = 'PAUSE'
+GCS_PROPAGATE = 'PROPAGATE'
+GCS_ATOMIC = 'ATOMIC'
+GCS_SWEEPSTRING = 'SWEEPSTRING'
+GCS_SWEEP = 'SWEEP'
+GCS_FINALIZE = 'FINALIZE'
+
+RX_VALID_GC_STATES = r'({})'.format('|'.join([
+    GCS_PAUSE,
+    GCS_PROPAGATE,
+    GCS_ATOMIC,
+    GCS_SWEEPSTRING,
+    GCS_SWEEP,
+    GCS_FINALIZE,
+]))
+RX_INVALID_GC_STATE = r'INVALID'
+
 
 class TestCaseBase(unittest.TestCase):
     @classmethod
@@ -269,23 +286,24 @@ class TestLJArch(TestCaseBase):
     )
 
 
-class TestLJState(TestCaseBase):
-    extension_cmds = 'lj-state'
-    location = 'lj_cf_print'
-    lua_script = 'print(1)'
-    pattern = (
+def compose_lj_state_rx(rx_gc_state):
+    return (
         r'VM state: [A-Z]+\n'
-        r'GC state: [A-Z]+\n'
+        r'GC state: ' + rx_gc_state + '\n'
         r'JIT state: [A-Z]+\n'
     )
 
 
-class TestLJGC(TestCaseBase):
-    extension_cmds = 'lj-gc'
+class TestLJState(TestCaseBase):
+    extension_cmds = 'lj-state'
     location = 'lj_cf_print'
     lua_script = 'print(1)'
-    pattern = (
-        r'GC stats: [A-Z]+\n'
+    pattern = compose_lj_state_rx(RX_VALID_GC_STATES)
+
+
+def compose_gc_stats_rx(rx_gc_state):
+    return (
+        r'GC stats: ' + rx_gc_state + '\n'
         r'\ttotal: \d+\n'
         r'\tthreshold: \d+\n'
         r'\tdebt: \d+\n'
@@ -301,6 +319,64 @@ class TestLJGC(TestCaseBase):
     )
 
 
+class TestLJGC(TestCaseBase):
+    extension_cmds = 'lj-gc'
+    location = 'lj_cf_print'
+    lua_script = 'print(1)'
+    pattern = compose_gc_stats_rx(RX_VALID_GC_STATES)
+
+
+class TestGCStateBase(TestCaseBase):
+    extension_cmds = (
+        'lj-state\n'
+        'lj-gc\n'
+    )
+    lua_script = (
+        'local obj = newproxy(true)\n'
+        'getmetatable(obj).__gc = function() end\n'
+        'obj = nil\n'
+        'collectgarbage()\n'
+    )
+
+    @classmethod
+    def setUpClass(cls):
+        cls.pattern = (
+            compose_lj_state_rx(cls.gc_state) +
+            compose_gc_stats_rx(cls.gc_state)
+        )
+        super(TestGCStateBase, cls).setUpClass()
+
+
+class TestGCStatePause(TestGCStateBase):
+    gc_state = GCS_PAUSE
+    location = 'gc_mark_start'
+
+
+class TestGCStatePropagate(TestGCStateBase):
+    gc_state = GCS_PROPAGATE
+    location = 'propagatemark'
+
+
+class TestGCStateAtomic(TestGCStateBase):
+    gc_state = GCS_ATOMIC
+    location = 'atomic'
+
+
+class TestGCStateSweepString(TestGCStateBase):
+    gc_state = GCS_SWEEPSTRING
+    location = 'gc_sweep_str_chain'
+
+
+class TestGCStateSweep(TestGCStateBase):
+    gc_state = GCS_SWEEP
+    location = 'gc_sweep'
+
+
+class TestGCStateFinalize(TestGCStateBase):
+    gc_state = 'FINALIZE'
+    location = 'gc_finalize'
+
+
 STACK_RX = (
     r'-+ Red zone:\s+\d+ slots -+\n'
     r'(' + RX_ADDR + r'\s+' + RX_FRAME + r' VALUE: nil\n?)*\n'
-- 
2.43.0


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

* [Tarantool-patches] [PATCH luajit v2] dbg: remove wrong GC state
  2026-10-15  7:20 [Tarantool-patches] [PATCH luajit] dbg: remove wrong GC state Mikhail Elhimov via Tarantool-patches
@ 2026-10-15 23:45 ` Mikhail Elhimov via Tarantool-patches
  2026-10-16 12:54   ` Sergey Kaplun via Tarantool-patches
                     ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Mikhail Elhimov via Tarantool-patches @ 2026-10-15 23:45 UTC (permalink / raw)
  To: Sergey Kaplun, Sergey Bronnikov, Evgeniy Temirgaleev; +Cc: tarantool-patches

It has been copied by mistake from the LuaVela fork of LuaJIT.
---
Changes in v2:
  * Rebased onto https://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html to avoid conflicts

This patch is to be applied after https://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html

Branch: https://github.com/tarantool/luajit/tree/elhimov/gh-noticket-dbg-remove-wrong-gcstate

 src/luajit_dbg.py                             |  3 +-
 .../debug-extension-tests.py                  | 96 +++++++++++++++++--
 2 files changed, 87 insertions(+), 12 deletions(-)

diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
index a685ecfa..8f7249ab 100644
--- a/src/luajit_dbg.py
+++ b/src/luajit_dbg.py
@@ -1244,7 +1244,6 @@ def gc_state(g):
         3: 'SWEEPSTRING',
         4: 'SWEEP',
         5: 'FINALIZE',
-        6: 'LAST',
     }.get(int(g['gc']['state']), 'INVALID')
 
 
@@ -2850,7 +2849,7 @@ LJState.__doc__ = '''
 lj-state
 The command requires no args and dumps current VM and GC states:
 * VM state: <{}>
-* GC state: <PAUSE|PROPAGATE|ATOMIC|SWEEPSTRING|SWEEP|FINALIZE|LAST>
+* GC state: <PAUSE|PROPAGATE|ATOMIC|SWEEPSTRING|SWEEP|FINALIZE>
 * JIT state: <IDLE|ACTIVE|RECORD|START|END|ASM|ERR>
     '''.format('|'.join(VM_STATES))
 
diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py
index bbd53dcc..735de2cb 100644
--- a/test/tarantool-debugger-tests/debug-extension-tests.py
+++ b/test/tarantool-debugger-tests/debug-extension-tests.py
@@ -133,6 +133,23 @@ elif machine == 'arm64' or machine == 'aarch64':
 else:
     raise Exception('Unknown architecture in testing')
 
+GCS_PAUSE = 'PAUSE'
+GCS_PROPAGATE = 'PROPAGATE'
+GCS_ATOMIC = 'ATOMIC'
+GCS_SWEEPSTRING = 'SWEEPSTRING'
+GCS_SWEEP = 'SWEEP'
+GCS_FINALIZE = 'FINALIZE'
+
+RX_VALID_GC_STATES = r'({})'.format('|'.join([
+    GCS_PAUSE,
+    GCS_PROPAGATE,
+    GCS_ATOMIC,
+    GCS_SWEEPSTRING,
+    GCS_SWEEP,
+    GCS_FINALIZE,
+]))
+RX_INVALID_GC_STATE = r'INVALID'
+
 
 class TestCaseBase(unittest.TestCase):
     @classmethod
@@ -283,23 +300,24 @@ RX_VM_STATE = '({})'.format('|'.join([
 ]))
 
 
-class TestLJState(TestCaseBase):
-    extension_cmds = 'lj-state'
-    location = 'lj_cf_print'
-    lua_script = 'print(1)'
-    pattern = (
+def compose_lj_state_rx(rx_gc_state):
+    return (
         r'VM state: ' + RX_VM_STATE + '\n'
-        r'GC state: [A-Z]+\n'
+        r'GC state: ' + rx_gc_state + '\n'
         r'JIT state: [A-Z]+\n'
     )
 
 
-class TestLJGC(TestCaseBase):
-    extension_cmds = 'lj-gc'
+class TestLJState(TestCaseBase):
+    extension_cmds = 'lj-state'
     location = 'lj_cf_print'
     lua_script = 'print(1)'
-    pattern = (
-        r'GC stats: [A-Z]+\n'
+    pattern = compose_lj_state_rx(RX_VALID_GC_STATES)
+
+
+def compose_gc_stats_rx(rx_gc_state):
+    return (
+        r'GC stats: ' + rx_gc_state + '\n'
         r'\ttotal: \d+\n'
         r'\tthreshold: \d+\n'
         r'\tdebt: \d+\n'
@@ -315,6 +333,64 @@ class TestLJGC(TestCaseBase):
     )
 
 
+class TestLJGC(TestCaseBase):
+    extension_cmds = 'lj-gc'
+    location = 'lj_cf_print'
+    lua_script = 'print(1)'
+    pattern = compose_gc_stats_rx(RX_VALID_GC_STATES)
+
+
+class TestGCStateBase(TestCaseBase):
+    extension_cmds = (
+        'lj-state\n'
+        'lj-gc\n'
+    )
+    lua_script = (
+        'local obj = newproxy(true)\n'
+        'getmetatable(obj).__gc = function() end\n'
+        'obj = nil\n'
+        'collectgarbage()\n'
+    )
+
+    @classmethod
+    def setUpClass(cls):
+        cls.pattern = (
+            compose_lj_state_rx(cls.gc_state) +
+            compose_gc_stats_rx(cls.gc_state)
+        )
+        super(TestGCStateBase, cls).setUpClass()
+
+
+class TestGCStatePause(TestGCStateBase):
+    gc_state = GCS_PAUSE
+    location = 'gc_mark_start'
+
+
+class TestGCStatePropagate(TestGCStateBase):
+    gc_state = GCS_PROPAGATE
+    location = 'propagatemark'
+
+
+class TestGCStateAtomic(TestGCStateBase):
+    gc_state = GCS_ATOMIC
+    location = 'atomic'
+
+
+class TestGCStateSweepString(TestGCStateBase):
+    gc_state = GCS_SWEEPSTRING
+    location = 'gc_sweep_str_chain'
+
+
+class TestGCStateSweep(TestGCStateBase):
+    gc_state = GCS_SWEEP
+    location = 'gc_sweep'
+
+
+class TestGCStateFinalize(TestGCStateBase):
+    gc_state = 'FINALIZE'
+    location = 'gc_finalize'
+
+
 STACK_RX = (
     r'-+ Red zone:\s+\d+ slots -+\n'
     r'(' + RX_ADDR + r'\s+' + RX_FRAME + r' VALUE: nil\n?)*\n'
-- 
2.43.0


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

* Re: [Tarantool-patches] [PATCH luajit v2] dbg: remove wrong GC state
  2026-10-15 23:45 ` [Tarantool-patches] [PATCH luajit v2] " Mikhail Elhimov via Tarantool-patches
@ 2026-10-16 12:54   ` Sergey Kaplun via Tarantool-patches
  2026-10-17  8:39     ` Mikhail Elhimov via Tarantool-patches
  2026-10-16 14:49   ` Sergey Bronnikov via Tarantool-patches
  2026-10-17  8:32   ` [Tarantool-patches] [PATCH luajit v3] " Mikhail Elhimov via Tarantool-patches
  2 siblings, 1 reply; 6+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2026-10-16 12:54 UTC (permalink / raw)
  To: Mikhail Elhimov; +Cc: tarantool-patches

Hi, Mikhail!
Thanks for the patch!
LGTM, after adding the comment for the testing snippet, see below.

On 16.10.26, Mikhail Elhimov wrote:
> It has been copied by mistake from the LuaVela fork of LuaJIT.
> ---
> Changes in v2:
>   * Rebased onto https://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html to avoid conflicts
> 
> This patch is to be applied after https://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html
> 
> Branch: https://github.com/tarantool/luajit/tree/elhimov/gh-noticket-dbg-remove-wrong-gcstate
> 
>  src/luajit_dbg.py                             |  3 +-
>  .../debug-extension-tests.py                  | 96 +++++++++++++++++--
>  2 files changed, 87 insertions(+), 12 deletions(-)
> 
> diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
> index a685ecfa..8f7249ab 100644
> --- a/src/luajit_dbg.py
> +++ b/src/luajit_dbg.py

<snipped>

> diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py
> index bbd53dcc..735de2cb 100644
> --- a/test/tarantool-debugger-tests/debug-extension-tests.py
> +++ b/test/tarantool-debugger-tests/debug-extension-tests.py

<snipped>

> +class TestGCStateBase(TestCaseBase):
> +    extension_cmds = (
> +        'lj-state\n'
> +        'lj-gc\n'
> +    )
> +    lua_script = (
> +        'local obj = newproxy(true)\n'
> +        'getmetatable(obj).__gc = function() end\n'
> +        'obj = nil\n'
> +        'collectgarbage()\n'
> +    )

It would be nice to add the comment here explaining why __all__ GC
states are reachable through this Lua code:
1) `gc_mark_start()` (GCpause) is always present in the full GC cycle.
2) `propagatemark()` (GCSpropagate) is reachable because our build has
   FFI and the finalizer table is marked as a weak table, i.e. it is
   grey. Hence, the g->gc.gray list is not empty.
3) `atomic()` (GCSatomic) is always present in the full GC cycle.
4) `gc_sweep_str_chain()` (GCSsweepstring) is always present in the full
   GC cycle.
5) `gc_sweep()` (GCSsweep) is always present in the full GC cycle.
6) `gc_finalize()` is met due to the finalizer to userdata in the
   script.

> +
> +    @classmethod
> +    def setUpClass(cls):
> +        cls.pattern = (
> +            compose_lj_state_rx(cls.gc_state) +
> +            compose_gc_stats_rx(cls.gc_state)
> +        )
> +        super(TestGCStateBase, cls).setUpClass()
> +
> +
> +class TestGCStatePause(TestGCStateBase):
> +    gc_state = GCS_PAUSE
> +    location = 'gc_mark_start'
> +
> +
> +class TestGCStatePropagate(TestGCStateBase):
> +    gc_state = GCS_PROPAGATE
> +    location = 'propagatemark'
> +
> +
> +class TestGCStateAtomic(TestGCStateBase):
> +    gc_state = GCS_ATOMIC
> +    location = 'atomic'
> +
> +
> +class TestGCStateSweepString(TestGCStateBase):
> +    gc_state = GCS_SWEEPSTRING
> +    location = 'gc_sweep_str_chain'
> +
> +
> +class TestGCStateSweep(TestGCStateBase):
> +    gc_state = GCS_SWEEP
> +    location = 'gc_sweep'
> +
> +
> +class TestGCStateFinalize(TestGCStateBase):
> +    gc_state = 'FINALIZE'
> +    location = 'gc_finalize'
> +
> +
>  STACK_RX = (
>      r'-+ Red zone:\s+\d+ slots -+\n'
>      r'(' + RX_ADDR + r'\s+' + RX_FRAME + r' VALUE: nil\n?)*\n'
> -- 
> 2.43.0
> 

-- 
Best regards,
Sergey Kaplun

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

* Re: [Tarantool-patches] [PATCH luajit v2] dbg: remove wrong GC state
  2026-10-15 23:45 ` [Tarantool-patches] [PATCH luajit v2] " Mikhail Elhimov via Tarantool-patches
  2026-10-16 12:54   ` Sergey Kaplun via Tarantool-patches
@ 2026-10-16 14:49   ` Sergey Bronnikov via Tarantool-patches
  2026-10-17  8:32   ` [Tarantool-patches] [PATCH luajit v3] " Mikhail Elhimov via Tarantool-patches
  2 siblings, 0 replies; 6+ messages in thread
From: Sergey Bronnikov via Tarantool-patches @ 2026-10-16 14:49 UTC (permalink / raw)
  To: Mikhail Elhimov, Sergey Kaplun, Evgeniy Temirgaleev; +Cc: tarantool-patches

Hi, Mikhail,

thanks for the patch! LGTM

Sergey

On 10/16/26 02:45, Mikhail Elhimov wrote:
> It has been copied by mistake from the LuaVela fork of LuaJIT.
> ---
> Changes in v2:
>    * Rebased onto https://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html to avoid conflicts
>
> This patch is to be applied after https://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html
>
> Branch: https://github.com/tarantool/luajit/tree/elhimov/gh-noticket-dbg-remove-wrong-gcstate
>
>   src/luajit_dbg.py                             |  3 +-
>   .../debug-extension-tests.py                  | 96 +++++++++++++++++--
>   2 files changed, 87 insertions(+), 12 deletions(-)
>
> diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
> index a685ecfa..8f7249ab 100644
> --- a/src/luajit_dbg.py
> +++ b/src/luajit_dbg.py
> @@ -1244,7 +1244,6 @@ def gc_state(g):
>           3: 'SWEEPSTRING',
>           4: 'SWEEP',
>           5: 'FINALIZE',
> -        6: 'LAST',
>       }.get(int(g['gc']['state']), 'INVALID')
>   
>   
> @@ -2850,7 +2849,7 @@ LJState.__doc__ = '''
>   lj-state
>   The command requires no args and dumps current VM and GC states:
>   * VM state: <{}>
> -* GC state: <PAUSE|PROPAGATE|ATOMIC|SWEEPSTRING|SWEEP|FINALIZE|LAST>
> +* GC state: <PAUSE|PROPAGATE|ATOMIC|SWEEPSTRING|SWEEP|FINALIZE>
>   * JIT state: <IDLE|ACTIVE|RECORD|START|END|ASM|ERR>
>       '''.format('|'.join(VM_STATES))
>   
> diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py
> index bbd53dcc..735de2cb 100644
> --- a/test/tarantool-debugger-tests/debug-extension-tests.py
> +++ b/test/tarantool-debugger-tests/debug-extension-tests.py
> @@ -133,6 +133,23 @@ elif machine == 'arm64' or machine == 'aarch64':
>   else:
>       raise Exception('Unknown architecture in testing')
>   
> +GCS_PAUSE = 'PAUSE'
> +GCS_PROPAGATE = 'PROPAGATE'
> +GCS_ATOMIC = 'ATOMIC'
> +GCS_SWEEPSTRING = 'SWEEPSTRING'
> +GCS_SWEEP = 'SWEEP'
> +GCS_FINALIZE = 'FINALIZE'
> +
> +RX_VALID_GC_STATES = r'({})'.format('|'.join([
> +    GCS_PAUSE,
> +    GCS_PROPAGATE,
> +    GCS_ATOMIC,
> +    GCS_SWEEPSTRING,
> +    GCS_SWEEP,
> +    GCS_FINALIZE,
> +]))
> +RX_INVALID_GC_STATE = r'INVALID'
> +
>   
>   class TestCaseBase(unittest.TestCase):
>       @classmethod
> @@ -283,23 +300,24 @@ RX_VM_STATE = '({})'.format('|'.join([
>   ]))
>   
>   
> -class TestLJState(TestCaseBase):
> -    extension_cmds = 'lj-state'
> -    location = 'lj_cf_print'
> -    lua_script = 'print(1)'
> -    pattern = (
> +def compose_lj_state_rx(rx_gc_state):
> +    return (
>           r'VM state: ' + RX_VM_STATE + '\n'
> -        r'GC state: [A-Z]+\n'
> +        r'GC state: ' + rx_gc_state + '\n'
>           r'JIT state: [A-Z]+\n'
>       )
>   
>   
> -class TestLJGC(TestCaseBase):
> -    extension_cmds = 'lj-gc'
> +class TestLJState(TestCaseBase):
> +    extension_cmds = 'lj-state'
>       location = 'lj_cf_print'
>       lua_script = 'print(1)'
> -    pattern = (
> -        r'GC stats: [A-Z]+\n'
> +    pattern = compose_lj_state_rx(RX_VALID_GC_STATES)
> +
> +
> +def compose_gc_stats_rx(rx_gc_state):
> +    return (
> +        r'GC stats: ' + rx_gc_state + '\n'
>           r'\ttotal: \d+\n'
>           r'\tthreshold: \d+\n'
>           r'\tdebt: \d+\n'
> @@ -315,6 +333,64 @@ class TestLJGC(TestCaseBase):
>       )
>   
>   
> +class TestLJGC(TestCaseBase):
> +    extension_cmds = 'lj-gc'
> +    location = 'lj_cf_print'
> +    lua_script = 'print(1)'
> +    pattern = compose_gc_stats_rx(RX_VALID_GC_STATES)
> +
> +
> +class TestGCStateBase(TestCaseBase):
> +    extension_cmds = (
> +        'lj-state\n'
> +        'lj-gc\n'
> +    )
> +    lua_script = (
> +        'local obj = newproxy(true)\n'
> +        'getmetatable(obj).__gc = function() end\n'
> +        'obj = nil\n'
> +        'collectgarbage()\n'
> +    )
> +
> +    @classmethod
> +    def setUpClass(cls):
> +        cls.pattern = (
> +            compose_lj_state_rx(cls.gc_state) +
> +            compose_gc_stats_rx(cls.gc_state)
> +        )
> +        super(TestGCStateBase, cls).setUpClass()
> +
> +
> +class TestGCStatePause(TestGCStateBase):
> +    gc_state = GCS_PAUSE
> +    location = 'gc_mark_start'
> +
> +
> +class TestGCStatePropagate(TestGCStateBase):
> +    gc_state = GCS_PROPAGATE
> +    location = 'propagatemark'
> +
> +
> +class TestGCStateAtomic(TestGCStateBase):
> +    gc_state = GCS_ATOMIC
> +    location = 'atomic'
> +
> +
> +class TestGCStateSweepString(TestGCStateBase):
> +    gc_state = GCS_SWEEPSTRING
> +    location = 'gc_sweep_str_chain'
> +
> +
> +class TestGCStateSweep(TestGCStateBase):
> +    gc_state = GCS_SWEEP
> +    location = 'gc_sweep'
> +
> +
> +class TestGCStateFinalize(TestGCStateBase):
> +    gc_state = 'FINALIZE'
> +    location = 'gc_finalize'
> +
> +
>   STACK_RX = (
>       r'-+ Red zone:\s+\d+ slots -+\n'
>       r'(' + RX_ADDR + r'\s+' + RX_FRAME + r' VALUE: nil\n?)*\n'

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

* [Tarantool-patches] [PATCH luajit v3] dbg: remove wrong GC state
  2026-10-15 23:45 ` [Tarantool-patches] [PATCH luajit v2] " Mikhail Elhimov via Tarantool-patches
  2026-10-16 12:54   ` Sergey Kaplun via Tarantool-patches
  2026-10-16 14:49   ` Sergey Bronnikov via Tarantool-patches
@ 2026-10-17  8:32   ` Mikhail Elhimov via Tarantool-patches
  2 siblings, 0 replies; 6+ messages in thread
From: Mikhail Elhimov via Tarantool-patches @ 2026-10-17  8:32 UTC (permalink / raw)
  To: Sergey Kaplun, Sergey Bronnikov, Evgeniy Temirgaleev; +Cc: tarantool-patches

It was copied originally by mistake from the LuaVela fork of LuaJIT.
---
Changes in v3:
  * Added comment about reachability of all the GC states from the same lua script

Changes in v2:
  * Rebased onto https://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html to avoid conflicts

This patch is to be applied after https://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html

Branch: https://github.com/tarantool/luajit/tree/elhimov/gh-noticket-dbg-remove-wrong-gcstate

 src/luajit_dbg.py                             |   3 +-
 .../debug-extension-tests.py                  | 113 ++++++++++++++++--
 2 files changed, 104 insertions(+), 12 deletions(-)

diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
index a685ecfa..8f7249ab 100644
--- a/src/luajit_dbg.py
+++ b/src/luajit_dbg.py
@@ -1244,7 +1244,6 @@ def gc_state(g):
         3: 'SWEEPSTRING',
         4: 'SWEEP',
         5: 'FINALIZE',
-        6: 'LAST',
     }.get(int(g['gc']['state']), 'INVALID')
 
 
@@ -2850,7 +2849,7 @@ LJState.__doc__ = '''
 lj-state
 The command requires no args and dumps current VM and GC states:
 * VM state: <{}>
-* GC state: <PAUSE|PROPAGATE|ATOMIC|SWEEPSTRING|SWEEP|FINALIZE|LAST>
+* GC state: <PAUSE|PROPAGATE|ATOMIC|SWEEPSTRING|SWEEP|FINALIZE>
 * JIT state: <IDLE|ACTIVE|RECORD|START|END|ASM|ERR>
     '''.format('|'.join(VM_STATES))
 
diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py
index bbd53dcc..9b6484ca 100644
--- a/test/tarantool-debugger-tests/debug-extension-tests.py
+++ b/test/tarantool-debugger-tests/debug-extension-tests.py
@@ -133,6 +133,23 @@ elif machine == 'arm64' or machine == 'aarch64':
 else:
     raise Exception('Unknown architecture in testing')
 
+GCS_PAUSE = 'PAUSE'
+GCS_PROPAGATE = 'PROPAGATE'
+GCS_ATOMIC = 'ATOMIC'
+GCS_SWEEPSTRING = 'SWEEPSTRING'
+GCS_SWEEP = 'SWEEP'
+GCS_FINALIZE = 'FINALIZE'
+
+RX_VALID_GC_STATES = r'({})'.format('|'.join([
+    GCS_PAUSE,
+    GCS_PROPAGATE,
+    GCS_ATOMIC,
+    GCS_SWEEPSTRING,
+    GCS_SWEEP,
+    GCS_FINALIZE,
+]))
+RX_INVALID_GC_STATE = r'INVALID'
+
 
 class TestCaseBase(unittest.TestCase):
     @classmethod
@@ -283,23 +300,24 @@ RX_VM_STATE = '({})'.format('|'.join([
 ]))
 
 
-class TestLJState(TestCaseBase):
-    extension_cmds = 'lj-state'
-    location = 'lj_cf_print'
-    lua_script = 'print(1)'
-    pattern = (
+def compose_lj_state_rx(rx_gc_state):
+    return (
         r'VM state: ' + RX_VM_STATE + '\n'
-        r'GC state: [A-Z]+\n'
+        r'GC state: ' + rx_gc_state + '\n'
         r'JIT state: [A-Z]+\n'
     )
 
 
-class TestLJGC(TestCaseBase):
-    extension_cmds = 'lj-gc'
+class TestLJState(TestCaseBase):
+    extension_cmds = 'lj-state'
     location = 'lj_cf_print'
     lua_script = 'print(1)'
-    pattern = (
-        r'GC stats: [A-Z]+\n'
+    pattern = compose_lj_state_rx(RX_VALID_GC_STATES)
+
+
+def compose_gc_stats_rx(rx_gc_state):
+    return (
+        r'GC stats: ' + rx_gc_state + '\n'
         r'\ttotal: \d+\n'
         r'\tthreshold: \d+\n'
         r'\tdebt: \d+\n'
@@ -315,6 +333,81 @@ class TestLJGC(TestCaseBase):
     )
 
 
+class TestLJGC(TestCaseBase):
+    extension_cmds = 'lj-gc'
+    location = 'lj_cf_print'
+    lua_script = 'print(1)'
+    pattern = compose_gc_stats_rx(RX_VALID_GC_STATES)
+
+
+class TestGCStateBase(TestCaseBase):
+    extension_cmds = (
+        'lj-state\n'
+        'lj-gc\n'
+    )
+
+    # The same lua code is used to check all the GC states because
+    # it allows to reach any of them:
+    # 1) `gc_mark_start()` (PAUSE) is always present in the full
+    #    GC cycle.
+    # 2) `propagatemark()` (PROPAGATE) is reachable because our
+    #    build has FFI and the finalizer table is marked as a weak
+    #    table, i.e. it is gray. Hence, the g->gc.gray list is not
+    #    empty.
+    # 3) `atomic()` (ATOMIC) is always present in the full GC
+    #    cycle.
+    # 4) `gc_sweep_str_chain()` (SWEEPSTRING) is always present in
+    #    the full GC cycle.
+    # 5) `gc_sweep()` (SWEEP) is always present in the full GC
+    #    cycle.
+    # 6) `gc_finalize()` (FINALIZE) is met due to the finalizer to
+    #    userdata in the script.
+    lua_script = (
+        'local obj = newproxy(true)\n'
+        'getmetatable(obj).__gc = function() end\n'
+        'obj = nil\n'
+        'collectgarbage()\n'
+    )
+
+    @classmethod
+    def setUpClass(cls):
+        cls.pattern = (
+            compose_lj_state_rx(cls.gc_state) +
+            compose_gc_stats_rx(cls.gc_state)
+        )
+        super(TestGCStateBase, cls).setUpClass()
+
+
+class TestGCStatePause(TestGCStateBase):
+    gc_state = GCS_PAUSE
+    location = 'gc_mark_start'
+
+
+class TestGCStatePropagate(TestGCStateBase):
+    gc_state = GCS_PROPAGATE
+    location = 'propagatemark'
+
+
+class TestGCStateAtomic(TestGCStateBase):
+    gc_state = GCS_ATOMIC
+    location = 'atomic'
+
+
+class TestGCStateSweepString(TestGCStateBase):
+    gc_state = GCS_SWEEPSTRING
+    location = 'gc_sweep_str_chain'
+
+
+class TestGCStateSweep(TestGCStateBase):
+    gc_state = GCS_SWEEP
+    location = 'gc_sweep'
+
+
+class TestGCStateFinalize(TestGCStateBase):
+    gc_state = GCS_FINALIZE
+    location = 'gc_finalize'
+
+
 STACK_RX = (
     r'-+ Red zone:\s+\d+ slots -+\n'
     r'(' + RX_ADDR + r'\s+' + RX_FRAME + r' VALUE: nil\n?)*\n'
-- 
2.43.0


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

* Re: [Tarantool-patches] [PATCH luajit v2] dbg: remove wrong GC state
  2026-10-16 12:54   ` Sergey Kaplun via Tarantool-patches
@ 2026-10-17  8:39     ` Mikhail Elhimov via Tarantool-patches
  0 siblings, 0 replies; 6+ messages in thread
From: Mikhail Elhimov via Tarantool-patches @ 2026-10-17  8:39 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

[-- Attachment #1: Type: text/plain, Size: 3507 bytes --]

Hi, Sergey!

Thanks for the review!

On 16.10.2026 15:54, Sergey Kaplun wrote:
> Hi, Mikhail!
> Thanks for the patch!
> LGTM, after adding the comment for the testing snippet, see below.
>
> On 16.10.26, Mikhail Elhimov wrote:
>> It has been copied by mistake from the LuaVela fork of LuaJIT.
>> ---
>> Changes in v2:
>>    * Rebased ontohttps://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html to avoid conflicts
>>
>> This patch is to be applied afterhttps://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030859.html
>>
>> Branch:https://github.com/tarantool/luajit/tree/elhimov/gh-noticket-dbg-remove-wrong-gcstate
>>
>>   src/luajit_dbg.py                             |  3 +-
>>   .../debug-extension-tests.py                  | 96 +++++++++++++++++--
>>   2 files changed, 87 insertions(+), 12 deletions(-)
>>
>> diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
>> index a685ecfa..8f7249ab 100644
>> --- a/src/luajit_dbg.py
>> +++ b/src/luajit_dbg.py
> <snipped>
>
>> diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py
>> index bbd53dcc..735de2cb 100644
>> --- a/test/tarantool-debugger-tests/debug-extension-tests.py
>> +++ b/test/tarantool-debugger-tests/debug-extension-tests.py
> <snipped>
>
>> +class TestGCStateBase(TestCaseBase):
>> +    extension_cmds = (
>> +        'lj-state\n'
>> +        'lj-gc\n'
>> +    )
>> +    lua_script = (
>> +        'local obj = newproxy(true)\n'
>> +        'getmetatable(obj).__gc = function() end\n'
>> +        'obj = nil\n'
>> +        'collectgarbage()\n'
>> +    )
> It would be nice to add the comment here explaining why __all__ GC
> states are reachable through this Lua code:
> 1) `gc_mark_start()` (GCpause) is always present in the full GC cycle.
> 2) `propagatemark()` (GCSpropagate) is reachable because our build has
>     FFI and the finalizer table is marked as a weak table, i.e. it is
>     grey. Hence, the g->gc.gray list is not empty.
> 3) `atomic()` (GCSatomic) is always present in the full GC cycle.
> 4) `gc_sweep_str_chain()` (GCSsweepstring) is always present in the full
>     GC cycle.
> 5) `gc_sweep()` (GCSsweep) is always present in the full GC cycle.
> 6) `gc_finalize()` is met due to the finalizer to userdata in the
>     script.
Done
>> +
>> +    @classmethod
>> +    def setUpClass(cls):
>> +        cls.pattern = (
>> +            compose_lj_state_rx(cls.gc_state) +
>> +            compose_gc_stats_rx(cls.gc_state)
>> +        )
>> +        super(TestGCStateBase, cls).setUpClass()
>> +
>> +
>> +class TestGCStatePause(TestGCStateBase):
>> +    gc_state = GCS_PAUSE
>> +    location = 'gc_mark_start'
>> +
>> +
>> +class TestGCStatePropagate(TestGCStateBase):
>> +    gc_state = GCS_PROPAGATE
>> +    location = 'propagatemark'
>> +
>> +
>> +class TestGCStateAtomic(TestGCStateBase):
>> +    gc_state = GCS_ATOMIC
>> +    location = 'atomic'
>> +
>> +
>> +class TestGCStateSweepString(TestGCStateBase):
>> +    gc_state = GCS_SWEEPSTRING
>> +    location = 'gc_sweep_str_chain'
>> +
>> +
>> +class TestGCStateSweep(TestGCStateBase):
>> +    gc_state = GCS_SWEEP
>> +    location = 'gc_sweep'
>> +
>> +
>> +class TestGCStateFinalize(TestGCStateBase):
>> +    gc_state = 'FINALIZE'
>> +    location = 'gc_finalize'
>> +
>> +
>>   STACK_RX = (
>>       r'-+ Redzone:\s+\d+ slots -+\n'
>>       r'(' + RX_ADDR + r'\s+' + RX_FRAME + r' VALUE: nil\n?)*\n'
>> -- 
>> 2.43.0
>>
-- 
Best regards,
Mikhail Elhimov

[-- Attachment #2: Type: text/html, Size: 4810 bytes --]

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

end of thread, other threads:[~2026-10-17  8:39 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-15  7:20 [Tarantool-patches] [PATCH luajit] dbg: remove wrong GC state Mikhail Elhimov via Tarantool-patches
2026-10-15 23:45 ` [Tarantool-patches] [PATCH luajit v2] " Mikhail Elhimov via Tarantool-patches
2026-10-16 12:54   ` Sergey Kaplun via Tarantool-patches
2026-10-17  8:39     ` Mikhail Elhimov via Tarantool-patches
2026-10-16 14:49   ` Sergey Bronnikov via Tarantool-patches
2026-10-17  8:32   ` [Tarantool-patches] [PATCH luajit v3] " Mikhail Elhimov 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