From cfaca8519151fd3f1398da0a9ced63ee3aa633f8 Mon Sep 17 00:00:00 2001 From: Daniele Parmeggiani Date: Fri, 17 Apr 2026 13:12:18 +0100 Subject: [PATCH 1/8] gh-142183: Change data stack to use a resizable array --- Include/cpython/pystate.h | 17 +-- Include/internal/pycore_debug_offsets.h | 4 +- Include/internal/pycore_interpframe.h | 68 +++++++-- Include/internal/pycore_runtime_init.h | 3 + .../debug_offsets_validation.h | 2 +- Modules/_remote_debugging/frames.c | 39 ++--- Python/ceval.c | 9 +- Python/pystate.c | 139 ++++++++---------- 8 files changed, 152 insertions(+), 129 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 1c56ad5af8072f..3d595e30714f6b 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -55,14 +55,14 @@ typedef struct _err_stackitem { } _PyErr_StackItem; typedef struct _stack_chunk { - struct _stack_chunk *previous; size_t size; - size_t top; - PyObject * data[1]; /* Variable sized */ + struct _stack_chunk *previous; + PyObject *data[1]; /* Variable sized */ } _PyStackChunk; -/* Minimum size of data stack chunk */ -#define _PY_DATA_STACK_CHUNK_SIZE (16*1024) +#define _PY_STACK_CHUNK_MIN_SIZE 4096 +#define _PY_STACK_CHUNK_OVERHEADS (offsetof(_PyStackChunk, data)) + struct _ts { /* See Python/ceval.c for comments explaining most fields */ @@ -195,10 +195,9 @@ struct _ts { /* Unique thread state id. */ uint64_t id; - _PyStackChunk *datastack_chunk; - PyObject **datastack_top; - PyObject **datastack_limit; - _PyStackChunk *datastack_cached_chunk; + _PyStackChunk *stack_chunk_list; + PyObject **stack_top; + PyObject **stack_limit; /* XXX signal handlers should also be here */ /* The following fields are here to avoid allocation during init. diff --git a/Include/internal/pycore_debug_offsets.h b/Include/internal/pycore_debug_offsets.h index c166f963da4f66..11868106dab142 100644 --- a/Include/internal/pycore_debug_offsets.h +++ b/Include/internal/pycore_debug_offsets.h @@ -106,7 +106,7 @@ typedef struct _Py_DebugOffsets { uint64_t last_profiled_frame; uint64_t thread_id; uint64_t native_thread_id; - uint64_t datastack_chunk; + uint64_t stack_chunk_list; uint64_t status; uint64_t holds_gil; uint64_t gil_requested; @@ -287,7 +287,7 @@ typedef struct _Py_DebugOffsets { .last_profiled_frame = offsetof(PyThreadState, last_profiled_frame), \ .thread_id = offsetof(PyThreadState, thread_id), \ .native_thread_id = offsetof(PyThreadState, native_thread_id), \ - .datastack_chunk = offsetof(PyThreadState, datastack_chunk), \ + .stack_chunk_list = offsetof(PyThreadState, stack_chunk_list), \ .status = offsetof(PyThreadState, _status), \ .holds_gil = offsetof(PyThreadState, holds_gil), \ .gil_requested = offsetof(PyThreadState, gil_requested), \ diff --git a/Include/internal/pycore_interpframe.h b/Include/internal/pycore_interpframe.h index d744dd12cd0479..0d5d1c84b3efe1 100644 --- a/Include/internal/pycore_interpframe.h +++ b/Include/internal/pycore_interpframe.h @@ -330,12 +330,12 @@ static inline bool _PyThreadState_HasStackSpace(PyThreadState *tstate, int size) { assert( - (tstate->datastack_top == NULL && tstate->datastack_limit == NULL) + (tstate->stack_top == NULL && tstate->stack_limit == NULL) || - (tstate->datastack_top != NULL && tstate->datastack_limit != NULL) + (tstate->stack_top != NULL && tstate->stack_limit != NULL) ); - return tstate->datastack_top != NULL && - size < tstate->datastack_limit - tstate->datastack_top; + return tstate->stack_top != NULL && + size < tstate->stack_limit - tstate->stack_top; } extern _PyInterpreterFrame * @@ -352,9 +352,9 @@ _PyFrame_PushUnchecked(PyThreadState *tstate, _PyStackRef func, int null_locals_ CALL_STAT_INC(frames_pushed); PyFunctionObject *func_obj = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(func); PyCodeObject *code = (PyCodeObject *)func_obj->func_code; - _PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)tstate->datastack_top; - tstate->datastack_top += code->co_framesize; - assert(tstate->datastack_top < tstate->datastack_limit); + _PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)tstate->stack_top; + tstate->stack_top += code->co_framesize; + assert(tstate->stack_top < tstate->stack_limit); _PyFrame_Initialize(tstate, new_frame, func, NULL, code, null_locals_from, previous); return new_frame; @@ -366,9 +366,9 @@ static inline _PyInterpreterFrame * _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int stackdepth, _PyInterpreterFrame * previous) { CALL_STAT_INC(frames_pushed); - _PyInterpreterFrame *frame = (_PyInterpreterFrame *)tstate->datastack_top; - tstate->datastack_top += code->co_framesize; - assert(tstate->datastack_top < tstate->datastack_limit); + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)tstate->stack_top; + tstate->stack_top += code->co_framesize; + assert(tstate->stack_top < tstate->stack_limit); frame->previous = previous; frame->f_funcobj = PyStackRef_None; frame->f_executable = PyStackRef_FromPyObjectNew(code); @@ -404,6 +404,54 @@ PyAPI_FUNC(_PyInterpreterFrame *) _PyEvalFramePushAndInit_Ex(PyThreadState *tstate, _PyStackRef func, PyObject *locals, Py_ssize_t nargs, PyObject *callargs, PyObject *kwargs, _PyInterpreterFrame *previous); +static inline bool +ptr_in_chunk(const char *ptr, const _PyStackChunk *chunk) +{ + assert(chunk != NULL); + const char *start = (char *)&chunk->data[0]; + const intptr_t offset = ptr - start; + const intptr_t usable_size = (intptr_t)(chunk->size - _PY_STACK_CHUNK_OVERHEADS); + return offset >= 0 && offset < usable_size && start + offset == ptr; +} + +static inline uintptr_t +get_offset_in_chunk(const char *ptr, const _PyStackChunk *chunk) +{ + assert(chunk != NULL); + assert(chunk->data != NULL); + assert(ptr_in_chunk(ptr, chunk)); + + return ptr - (char *)chunk; +} + +static inline uintptr_t +get_offset_in_chunk_list(char *base, _PyStackChunk *stack_chunk_list) +{ + assert(stack_chunk_list != NULL); + assert(base != NULL); + _PyStackChunk *chunk = stack_chunk_list; + do { + if (ptr_in_chunk(base, chunk)) { + return get_offset_in_chunk(base, chunk); + } + chunk = chunk->previous; + } while (chunk); + assert(false); // did not find correct chunk + Py_UNREACHABLE(); +} + +static inline void * +_Py_ensure_frame_in_current_stack_chunk(PyThreadState *tstate, char *frame) +{ + assert(tstate != NULL); + assert(frame != NULL); + if (ptr_in_chunk(frame, tstate->stack_chunk_list)) { + return frame; + } + uintptr_t offset = get_offset_in_chunk_list(frame, tstate->stack_chunk_list->previous); + return ((char *)tstate->stack_chunk_list) + offset; +} + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index e8d1098c2078fc..c9506bf340164b 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -179,6 +179,9 @@ extern PyTypeObject _PyExc_MemoryError; ._whence = _PyThreadState_WHENCE_NOTSET, \ .py_recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ .context_ver = 1, \ + .stack_chunk_list = NULL, \ + .stack_limit = NULL, \ + .stack_top = NULL, \ } diff --git a/Modules/_remote_debugging/debug_offsets_validation.h b/Modules/_remote_debugging/debug_offsets_validation.h index 32800e767b3169..73572c3875d3cd 100644 --- a/Modules/_remote_debugging/debug_offsets_validation.h +++ b/Modules/_remote_debugging/debug_offsets_validation.h @@ -252,7 +252,7 @@ validate_fixed_field( #define PY_REMOTE_DEBUG_THREAD_STATE_FIELDS(APPLY, buffer_size) \ APPLY(thread_state, native_thread_id, sizeof(unsigned long), _Alignof(long), buffer_size); \ APPLY(thread_state, interp, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \ - APPLY(thread_state, datastack_chunk, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \ + APPLY(thread_state, stack_chunk_list, sizeof(uintptr_t), _Alignof(uintptr_t), buffer_size); \ APPLY(thread_state, status, FIELD_SIZE(PyThreadState, _status), _Alignof(unsigned int), buffer_size); \ APPLY(thread_state, holds_gil, sizeof(int), _Alignof(int), buffer_size); \ APPLY(thread_state, gil_requested, sizeof(int), _Alignof(int), buffer_size); \ diff --git a/Modules/_remote_debugging/frames.c b/Modules/_remote_debugging/frames.c index bbdfce3f7201d9..133ae36ff994d6 100644 --- a/Modules/_remote_debugging/frames.c +++ b/Modules/_remote_debugging/frames.c @@ -27,7 +27,7 @@ process_single_stack_chunk( StackChunkInfo *chunk_info ) { // Start with default size assumption - size_t current_size = _PY_DATA_STACK_CHUNK_SIZE; + size_t current_size = _PY_STACK_CHUNK_MIN_SIZE; char *this_chunk = PyMem_RawMalloc(current_size); if (!this_chunk) { @@ -87,11 +87,17 @@ copy_stack_chunks(RemoteUnwinderObject *unwinder, size_t count = 0; size_t max_chunks = 16; - if (read_ptr(unwinder, tstate_addr + (uintptr_t)unwinder->debug_offsets.thread_state.datastack_chunk, &chunk_addr)) { + if (read_ptr(unwinder, tstate_addr + (uintptr_t)unwinder->debug_offsets.thread_state.stack_chunk_list, &chunk_addr)) { set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read initial stack chunk address"); return -1; } + if (!chunk_addr) { + out_chunks->chunks = NULL; + out_chunks->count = 0; + return 0; + } + chunks = PyMem_RawMalloc(max_chunks * sizeof(StackChunkInfo)); if (!chunks) { PyErr_NoMemory(); @@ -99,33 +105,14 @@ copy_stack_chunks(RemoteUnwinderObject *unwinder, return -1; } - const size_t MAX_STACK_CHUNKS = 4096; - while (chunk_addr != 0 && count < MAX_STACK_CHUNKS) { - // Grow array if needed - if (count >= max_chunks) { - max_chunks *= 2; - StackChunkInfo *new_chunks = PyMem_RawRealloc(chunks, max_chunks * sizeof(StackChunkInfo)); - if (!new_chunks) { - PyErr_NoMemory(); - set_exception_cause(unwinder, PyExc_MemoryError, "Failed to grow stack chunks array"); - goto error; - } - chunks = new_chunks; - } - - // Process this chunk - if (process_single_stack_chunk(unwinder, chunk_addr, &chunks[count]) < 0) { - set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to process stack chunk"); - goto error; - } - - // Get next chunk address and increment count - chunk_addr = GET_MEMBER(uintptr_t, chunks[count].local_copy, offsetof(_PyStackChunk, previous)); - count++; + // Process this chunk + if (process_single_stack_chunk(unwinder, chunk_addr, &chunks[count]) < 0) { + set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to process stack chunk"); + goto error; } out_chunks->chunks = chunks; - out_chunks->count = count; + out_chunks->count = 1; return 0; error: diff --git a/Python/ceval.c b/Python/ceval.c index ead0df31c44266..5d29ce7cb5c293 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1925,8 +1925,13 @@ clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) assert(frame->owner == FRAME_OWNED_BY_THREAD); // Make sure that this is, indeed, the top frame. We can't check this in // _PyThreadState_PopFrame, since f_code is already cleared at that point: - assert((PyObject **)frame + _PyFrame_GetCode(frame)->co_framesize == - tstate->datastack_top); + assert( + _Py_ensure_frame_in_current_stack_chunk( // the frame might be in a previous stack chunk + tstate, + (char *)((PyObject **)frame + _PyFrame_GetCode(frame)->co_framesize) + ) + == tstate->stack_top + ); assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); _PyFrame_ClearExceptCode(frame); PyStackRef_CLEAR(frame->f_executable); diff --git a/Python/pystate.c b/Python/pystate.c index 3f539a4c2551ba..bf85e7404dd833 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1433,17 +1433,16 @@ tstate_is_alive(PyThreadState *tstate) // lifecycle //---------- -static _PyStackChunk* -allocate_chunk(int size_in_bytes, _PyStackChunk* previous) +static _PyStackChunk * +allocate_stack_chunk(size_t size_in_bytes) { assert(size_in_bytes % sizeof(PyObject **) == 0); _PyStackChunk *res = _PyObject_VirtualAlloc(size_in_bytes); if (res == NULL) { return NULL; } - res->previous = previous; + res->previous = NULL; res->size = size_in_bytes; - res->top = 0; return res; } @@ -1572,10 +1571,9 @@ init_threadstate(_PyThreadStateImpl *_tstate, tstate->current_frame = &_tstate->base_frame; // base_frame pointer for profilers to validate stack unwinding tstate->base_frame = &_tstate->base_frame; - tstate->datastack_chunk = NULL; - tstate->datastack_top = NULL; - tstate->datastack_limit = NULL; - tstate->datastack_cached_chunk = NULL; + tstate->stack_chunk_list = NULL; + tstate->stack_top = NULL; + tstate->stack_limit = NULL; tstate->what_event = -1; tstate->current_executor = NULL; tstate->jit_exit = NULL; @@ -1717,20 +1715,17 @@ _PyThreadState_Init(PyThreadState *tstate) static void -clear_datastack(PyThreadState *tstate) +clear_stack_chunk_list(PyThreadState *tstate) { - _PyStackChunk *chunk = tstate->datastack_chunk; - tstate->datastack_chunk = NULL; - while (chunk != NULL) { - _PyStackChunk *prev = chunk->previous; - _PyObject_VirtualFree(chunk, chunk->size); - chunk = prev; - } - if (tstate->datastack_cached_chunk != NULL) { - _PyObject_VirtualFree(tstate->datastack_cached_chunk, - tstate->datastack_cached_chunk->size); - tstate->datastack_cached_chunk = NULL; + assert(tstate != NULL); + _PyStackChunk *chunk_list = tstate->stack_chunk_list; + while (chunk_list != NULL) { + _PyStackChunk *prev = chunk_list->previous; + size_t size = chunk_list->size; + _PyObject_VirtualFree(chunk_list, size); + chunk_list = prev; } + tstate->stack_chunk_list = NULL; } void @@ -1932,7 +1927,7 @@ tstate_delete_common(PyThreadState *tstate, int release_gil) } // XXX Move to PyThreadState_Clear()? - clear_datastack(tstate); + clear_stack_chunk_list(tstate); if (release_gil) { _PyEval_ReleaseLock(tstate->interp, tstate, 1); @@ -3052,42 +3047,44 @@ _PyInterpreterState_HasFeature(PyInterpreterState *interp, unsigned long feature return ((interp->feature_flags & feature) != 0); } - -#define MINIMUM_OVERHEAD 1000 +#define MINIMUM_OVERHEAD 0 static PyObject ** -push_chunk(PyThreadState *tstate, int size) -{ - int allocate_size = _PY_DATA_STACK_CHUNK_SIZE; - while (allocate_size < (int)sizeof(PyObject*)*(size + MINIMUM_OVERHEAD)) { +resize_stack(PyThreadState *tstate, int size) +{ + size_t current_size, allocate_size; + _PyStackChunk *old = tstate->stack_chunk_list; + if (old) { + current_size = tstate->stack_chunk_list->size; + assert(current_size > 0); + allocate_size = current_size * 2; + } else { + current_size = 0; + allocate_size = _PY_STACK_CHUNK_MIN_SIZE; + } + assert(allocate_size > current_size); + assert(allocate_size - current_size > _PY_STACK_CHUNK_OVERHEADS); + size_t required_space = sizeof(PyObject *) * (size + MINIMUM_OVERHEAD) + _PY_STACK_CHUNK_OVERHEADS; + while (allocate_size < required_space) { allocate_size *= 2; } - _PyStackChunk *new; - if (tstate->datastack_cached_chunk != NULL - && (size_t)allocate_size <= tstate->datastack_cached_chunk->size) - { - new = tstate->datastack_cached_chunk; - tstate->datastack_cached_chunk = NULL; - new->previous = tstate->datastack_chunk; - new->top = 0; - } - else { - new = allocate_chunk(allocate_size, tstate->datastack_chunk); - if (new == NULL) { - return NULL; - } + assert(allocate_size > 0); + _PyStackChunk *new = allocate_stack_chunk(allocate_size); + if (new == NULL) { + return NULL; } - if (tstate->datastack_chunk) { - tstate->datastack_chunk->top = tstate->datastack_top - - &tstate->datastack_chunk->data[0]; - } - tstate->datastack_chunk = new; - tstate->datastack_limit = (PyObject **)(((char *)new) + allocate_size); - // When new is the "root" chunk (i.e. new->previous == NULL), we can keep - // _PyThreadState_PopFrame from freeing it later by "skipping" over the - // first element: - PyObject **res = &new->data[new->previous == NULL]; - tstate->datastack_top = res + size; + if (old) { + new->previous = old; + long current_stack_size = tstate->stack_top - &old->data[0]; + assert(current_stack_size > 0); + tstate->stack_top = &new->data[current_stack_size]; + } else { + tstate->stack_top = &new->data[0]; + } + tstate->stack_chunk_list = new; + tstate->stack_limit = (PyObject **)(((char *)new) + allocate_size); + PyObject **res = tstate->stack_top; + tstate->stack_top = res + size; return res; } @@ -3096,38 +3093,22 @@ _PyThreadState_PushFrame(PyThreadState *tstate, size_t size) { assert(size < INT_MAX/sizeof(PyObject *)); if (_PyThreadState_HasStackSpace(tstate, (int)size)) { - _PyInterpreterFrame *res = (_PyInterpreterFrame *)tstate->datastack_top; - tstate->datastack_top += size; + _PyInterpreterFrame *res = (_PyInterpreterFrame *)tstate->stack_top; + tstate->stack_top += size; return res; } - return (_PyInterpreterFrame *)push_chunk(tstate, (int)size); + return (_PyInterpreterFrame *) resize_stack(tstate, (int) size); } void -_PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) -{ - assert(tstate->datastack_chunk); - PyObject **base = (PyObject **)frame; - if (base == &tstate->datastack_chunk->data[0]) { - _PyStackChunk *chunk = tstate->datastack_chunk; - _PyStackChunk *previous = chunk->previous; - _PyStackChunk *cached = tstate->datastack_cached_chunk; - // push_chunk ensures that the root chunk is never popped: - assert(previous); - tstate->datastack_top = &previous->data[previous->top]; - tstate->datastack_chunk = previous; - tstate->datastack_limit = (PyObject **)(((char *)previous) + previous->size); - chunk->previous = NULL; - if (cached != NULL) { - _PyObject_VirtualFree(cached, cached->size); - } - tstate->datastack_cached_chunk = chunk; - } - else { - assert(tstate->datastack_top); - assert(tstate->datastack_top >= base); - tstate->datastack_top = base; - } +_PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame) +{ + assert(tstate->stack_chunk_list); + PyObject **base = (PyObject **)_Py_ensure_frame_in_current_stack_chunk(tstate, (char *)frame); + assert(ptr_in_chunk((char *)base, tstate->stack_chunk_list)); + assert(tstate->stack_top); + assert(tstate->stack_top >= base); + tstate->stack_top = base; } From bb087392fc8e1a8902494ae28aacb15ddbc81070 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 12:27:37 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-04-17-12-27-33.gh-issue-142183.jKFUky.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-04-17-12-27-33.gh-issue-142183.jKFUky.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-17-12-27-33.gh-issue-142183.jKFUky.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-17-12-27-33.gh-issue-142183.jKFUky.rst new file mode 100644 index 00000000000000..7be9d1cf8ae1eb --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-17-12-27-33.gh-issue-142183.jKFUky.rst @@ -0,0 +1 @@ +Change the resizing implementation of the Python stack to use a resizable array instead of a chain of arrays, to avoid degenerate performance cases and allow further JIT optimizations. From 99bb502d1417111c92b3dc105f1141d1fab71545 Mon Sep 17 00:00:00 2001 From: Daniele Parmeggiani Date: Mon, 20 Apr 2026 13:33:25 +0100 Subject: [PATCH 3/8] skip tests failing on emscripten --- Lib/test/test_isinstance.py | 2 ++ Lib/test/test_pyrepl/test_unix_console.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index d97535ba46e677..54966c1178e234 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -307,6 +307,8 @@ def __bases__(self): self.assertEqual(True, issubclass(B(), int)) + @support.skip_emscripten_stack_overflow() + @support.skip_wasi_stack_overflow() def test_infinite_recursion_in_bases(self): class X: @property diff --git a/Lib/test/test_pyrepl/test_unix_console.py b/Lib/test/test_pyrepl/test_unix_console.py index 71b2e17e334151..8e60d7628aaebb 100644 --- a/Lib/test/test_pyrepl/test_unix_console.py +++ b/Lib/test/test_pyrepl/test_unix_console.py @@ -7,7 +7,7 @@ import unittest from functools import partial from test.support import force_color, os_helper, force_not_colorized_test_class -from test.support import threading_helper +from test.support import threading_helper, is_emscripten from unittest import TestCase from unittest.mock import MagicMock, call, patch, ANY, Mock @@ -349,6 +349,7 @@ def same_console(events): console.restore() con.restore() + @unittest.skipIf(is_emscripten, "Causes TypeError: Cannot read properties of undefined (reading '0')") def test_getheightwidth_with_invalid_environ(self, _os_write): # gh-128636 console = UnixConsole(term="xterm") @@ -384,6 +385,7 @@ def test_restore_in_thread(self, _os_write): @unittest.skipIf(sys.platform == "win32", "No Unix console on Windows") class TestUnixConsoleEIOHandling(TestCase): + @unittest.skipIf(is_emscripten, "Causes TypeError: Cannot read properties of undefined (reading '0')") @patch('_pyrepl.unix_console.tcsetattr') @patch('_pyrepl.unix_console.tcgetattr') def test_eio_error_handling_in_restore(self, mock_tcgetattr, mock_tcsetattr): From 99e9e44e49cea6f1e1db745d1b29aeb0964d4fe4 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Tue, 28 Apr 2026 11:20:53 +0100 Subject: [PATCH 4/8] Fix regression in profiler module --- Lib/test/test_external_inspection.py | 50 +++++++++++++++++++ Modules/_remote_debugging/_remote_debugging.h | 1 + Modules/_remote_debugging/frames.c | 50 +++++++++++++++++-- Modules/_remote_debugging/module.c | 2 + 4 files changed, 98 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_external_inspection.py b/Lib/test/test_external_inspection.py index ec7192b1b89184..d2a89e63a6f223 100644 --- a/Lib/test/test_external_inspection.py +++ b/Lib/test/test_external_inspection.py @@ -3513,6 +3513,56 @@ def recurse(n): "Cache exhaustion should not affect stack completeness", ) + @skip_if_not_supported + @unittest.skipIf( + sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED, + "Test only runs on Linux with process_vm_readv support", + ) + def test_deep_stack_uses_copied_stack_chunks(self): + """Test deep stacks do not fall back to one remote read per frame.""" + depth = 1000 + script_body = f"""\ +import sys +sys.setrecursionlimit(2000) + +def recurse(n): + if n <= 0: + sock.sendall(b"ready") + sock.recv(16) + return + recurse(n - 1) + +recurse({depth}) +""" + + with self._target_process(script_body) as ( + p, + client_socket, + _, + ): + unwinder = RemoteUnwinder( + p.pid, all_threads=True, cache_frames=False, stats=True + ) + frames = self._sample_frames( + client_socket, + unwinder, + b"ready", + b"done", + {"recurse"}, + expected_frames=depth + 2, + ) + stats = unwinder.get_stats() + + self.assertIsNotNone(frames) + + recurse_count = [f.funcname for f in frames].count("recurse") + self.assertGreaterEqual(recurse_count, depth) + + # This stack spans multiple chunks. Copying only the current chunk + # forces older frames down the slow remote-read fallback path. + self.assertGreater(stats["stack_chunks_copied"], 1, stats) + self.assertLess(stats["memory_reads"], depth // 10, stats) + @skip_if_not_supported @unittest.skipIf( sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED, diff --git a/Modules/_remote_debugging/_remote_debugging.h b/Modules/_remote_debugging/_remote_debugging.h index 07738d45e42d24..f89b5630ad9cbb 100644 --- a/Modules/_remote_debugging/_remote_debugging.h +++ b/Modules/_remote_debugging/_remote_debugging.h @@ -239,6 +239,7 @@ typedef struct { uint64_t frames_read_from_memory; // Total frames read from remote memory uint64_t memory_reads; // Total remote memory read operations uint64_t memory_bytes_read; // Total bytes read from remote memory + uint64_t stack_chunks_copied; // Total stack chunks copied uint64_t code_object_cache_hits; // Code object cache hits uint64_t code_object_cache_misses; // Code object cache misses uint64_t stale_cache_invalidations; // Times stale entries were cleared diff --git a/Modules/_remote_debugging/frames.c b/Modules/_remote_debugging/frames.c index 133ae36ff994d6..1adc90421662e4 100644 --- a/Modules/_remote_debugging/frames.c +++ b/Modules/_remote_debugging/frames.c @@ -105,14 +105,54 @@ copy_stack_chunks(RemoteUnwinderObject *unwinder, return -1; } - // Process this chunk - if (process_single_stack_chunk(unwinder, chunk_addr, &chunks[count]) < 0) { - set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to process stack chunk"); - goto error; + const size_t MAX_STACK_CHUNKS = 4096; + while (chunk_addr != 0) { + if (count >= MAX_STACK_CHUNKS) { + PyErr_Format(PyExc_RuntimeError, + "Too many stack chunks (%zu) - possible corrupted remote memory", + count); + set_exception_cause(unwinder, PyExc_RuntimeError, + "Too many stack chunks"); + goto error; + } + + if (count >= max_chunks) { + max_chunks *= 2; + StackChunkInfo *new_chunks = PyMem_RawRealloc( + chunks, max_chunks * sizeof(StackChunkInfo)); + if (!new_chunks) { + PyErr_NoMemory(); + set_exception_cause(unwinder, PyExc_MemoryError, + "Failed to grow stack chunks array"); + goto error; + } + chunks = new_chunks; + } + + uintptr_t prev_addr = chunk_addr; + if (process_single_stack_chunk(unwinder, chunk_addr, + &chunks[count]) < 0) { + set_exception_cause(unwinder, PyExc_RuntimeError, + "Failed to process stack chunk"); + goto error; + } + STATS_INC(unwinder, stack_chunks_copied); + + chunk_addr = GET_MEMBER(uintptr_t, chunks[count].local_copy, + offsetof(_PyStackChunk, previous)); + count++; + + if (chunk_addr == prev_addr) { + PyErr_SetString(PyExc_RuntimeError, + "Stack chunk cycle detected (corrupted remote memory)"); + set_exception_cause(unwinder, PyExc_RuntimeError, + "Stack chunk cycle detected"); + goto error; + } } out_chunks->chunks = chunks; - out_chunks->count = 1; + out_chunks->count = count; return 0; error: diff --git a/Modules/_remote_debugging/module.c b/Modules/_remote_debugging/module.c index 32f2cbacf2143b..ac032784e20e40 100644 --- a/Modules/_remote_debugging/module.c +++ b/Modules/_remote_debugging/module.c @@ -878,6 +878,7 @@ RemoteUnwinder was created with stats=True. - frames_read_from_memory: Total frames read from remote memory - memory_reads: Total remote memory read operations - memory_bytes_read: Total bytes read from remote memory + - stack_chunks_copied: Total stack chunks copied from remote memory - code_object_cache_hits: Code object cache hits - code_object_cache_misses: Code object cache misses - stale_cache_invalidations: Times stale cache entries were cleared @@ -922,6 +923,7 @@ _remote_debugging_RemoteUnwinder_get_stats_impl(RemoteUnwinderObject *self) ADD_STAT(frames_read_from_memory); ADD_STAT(memory_reads); ADD_STAT(memory_bytes_read); + ADD_STAT(stack_chunks_copied); ADD_STAT(code_object_cache_hits); ADD_STAT(code_object_cache_misses); ADD_STAT(stale_cache_invalidations); From bab3d69d5baaf821a21a2214b1945506dbf601a0 Mon Sep 17 00:00:00 2001 From: Daniele Parmeggiani Date: Fri, 8 May 2026 13:59:52 +0100 Subject: [PATCH 5/8] improve docs --- InternalDocs/frames.md | 42 ++++- InternalDocs/images/stack-resize-pop-push.dot | 146 +++++++++++++++++ InternalDocs/images/stack-resize-pop-push.png | Bin 0 -> 39405 bytes InternalDocs/images/stack-resize.dot | 153 ++++++++++++++++++ InternalDocs/images/stack-resize.png | Bin 0 -> 68110 bytes 5 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 InternalDocs/images/stack-resize-pop-push.dot create mode 100644 InternalDocs/images/stack-resize-pop-push.png create mode 100644 InternalDocs/images/stack-resize.dot create mode 100644 InternalDocs/images/stack-resize.png diff --git a/InternalDocs/frames.md b/InternalDocs/frames.md index 60ab2055afa7b1..93954df9df1e95 100644 --- a/InternalDocs/frames.md +++ b/InternalDocs/frames.md @@ -18,12 +18,52 @@ The definition of the `_PyInterpreterFrame` struct is in Python semantics allows frames to outlive the activation, so they need to be allocated outside the C call stack. To reduce overhead and improve locality of reference, most frames are allocated contiguously in a per-thread stack -(see `_PyThreadState_PushFrame` in [Python/pystate.c](../Python/pystate.c)). +chunk (see `_PyThreadState_PushFrame` in +[Python/pystate.c](../Python/pystate.c)). Frames of generators and coroutines are embedded in the generator and coroutine objects, so are not allocated in the per-thread stack. See `_PyGenObject` in [Include/internal/pycore_interpframe_structs.h](../Include/internal/pycore_interpframe_structs.h). +## Stack allocation + +The per-thread stack is a resizable array backed by `_PyStackChunk` +allocations. Each `PyThreadState` stores: + +* `stack_chunk_list`: the newest stack chunk, with older chunks linked through + `_PyStackChunk.previous`; +* `stack_top`: the next free slot in the newest chunk; and +* `stack_limit`: the end of the newest chunk. + +The first frame allocation creates a chunk of at least +`_PY_STACK_CHUNK_MIN_SIZE=4096` bytes. If a subsequent frame does not fit, +`resize_stack()` allocates a larger chunk, twice the size of the +previous one and large enough for the requested frame. The old chunk is +retained in `stack_chunk_list->previous`, instead of being copied or +immediately freed. + +The newest chunk is aligned with the previous logical stack by setting its +`stack_top` to the same offset that was used in the old chunk. New frames are +then placed in the newest chunk. Existing frame records remain where they were, +so the `previous` links in the frame chain can cross from the newest chunk into +older retained chunks. + +![Resizable stack after a resize](images/stack-resize.png) + +When a frame is popped, `_PyThreadState_PopFrame()` ensures that +`tstate->stack_top` keeps pointing into the new stack chunk even if the popped +frame resides in an older chunk. This ensures that when new frames are pushed, +they are created in the new chunk. + +Starting from the situation depicted above, the picture below shows what happens +after resizing and a number of pops remove one frame in the older chunk, then a +new frame is created and placed in the newest chunk. + +![Stack after a resize, various pops and one push](images/stack-resize-pop-push.png) + +All retained stack chunks are freed when the thread state is deleted by +`clear_stack_chunk_list()`. + ## Layout Each activation record is laid out as: diff --git a/InternalDocs/images/stack-resize-pop-push.dot b/InternalDocs/images/stack-resize-pop-push.dot new file mode 100644 index 00000000000000..f7690b6c5866cc --- /dev/null +++ b/InternalDocs/images/stack-resize-pop-push.dot @@ -0,0 +1,146 @@ +digraph stack_resize { + graph [ + fontname="Monaco", + fontsize=16, + bgcolor="white", + compound=true, + newrank=true, + splines=false + ]; + + node [ + fontname="Monaco", + fontsize=16, + shape=box, + style="rounded,filled", + color="#2563eb", + fillcolor="white", + penwidth=2, + fixedsize=true + ]; + + edge [ + color="#111111", + fontname="Monaco", + penwidth=2, + arrowsize=0.75 + ]; + + subgraph cluster_older_chunk { + label="older chunk"; + labelloc=b; + fontcolor="#0f172a"; + style="rounded,filled"; + color="#334155"; + fillcolor="#f1f5f9"; + penwidth=2; + margin=24; + + node [ + color="#64748b", + width=2.5, + ]; + + old_frame_hidden [style="invis", label=""]; + old_frame_1 [style="invis", label=""]; + subgraph cluster_older_frames { + label=""; + penwidth=0; + old_frame_2 [label="older frame"]; + old_frame_3 [label="older frame"]; + } + old_previous [ + color="invis", + fillcolor="invis", + width=2.15, + height=0.58, + label="previous = NULL" + ]; + + old_frame_hidden:s -> old_frame_1:n [style="invis"]; + old_frame_1:s -> old_frame_2:n [style="invis"]; + old_frame_2:s -> old_frame_3:n; + old_frame_3:s -> old_previous:n [style="invis"]; + } + + subgraph cluster_newest_chunk { + label="newest chunk"; + labelloc=b; + fontcolor="#0f172a"; + style="rounded,filled"; + color="#1e3a8a"; + fillcolor="#eaf4ff"; + penwidth=2; + margin=24; + + newer_frame_hidden [width=2.5, style="invis"]; + top_frame [width=2.5, label="top frame", style="invis"]; + newer_frame_1 [width=2.5, label="newer frame", style="invis"]; + newer_frame_2 [width=2.5, label="top frame"]; + + subgraph cluster_untouched_memory { + label=""; + color="#f59e0b"; + fillcolor="#ffec99"; + style="filled,dashed"; + penwidth=2; + margin=24; + + node [ + width=2.5, + height=0.5, + ]; + + untouched_memory_top [style="invis", label=""]; + untouched_memory_bottom [style="invis", label=""]; + } + + new_previous [ + color="invis", + fillcolor="invis", + width=1.15, + height=0.58, + label="previous" + ]; + + newer_frame_hidden:s -> top_frame:n [style="invis"]; + top_frame:s -> newer_frame_1:n [style="invis"]; + newer_frame_1:s -> newer_frame_2:n [style="invis"]; + newer_frame_2:s -> untouched_memory_top:n [ + lhead=cluster_untouched_memory, + style="invis", + ]; + untouched_memory_bottom:s -> new_previous:n [ + ltail=cluster_untouched_memory, + style="invis", + ]; + } + + stack_top_label [ + shape=plaintext, + style="", + fixedsize=false, + label="stack_top", + fontcolor="#0f172a" + ]; + + { rank=same; old_frame_1; newer_frame_2; } + { rank=same; old_frame_2; untouched_memory_top; } + { rank=same; old_frame_3; untouched_memory_bottom; } + { rank=same; old_previous; new_previous; } + { rank=same; newer_frame_2; stack_top_label; } + + newer_frame_2 -> stack_top_label [style=invis, weight=100, constraint=false]; + old_frame_1 -> newer_frame_2 [style=invis, weight=100, constraint=false]; + + newer_frame_2:w -> old_frame_2:e [ + constraint=false, + ]; + stack_top_label:w -> newer_frame_2:e [ + constraint=false + ]; + new_previous:w -> old_previous:e [ + lhead=cluster_older_chunk, + constraint=false + ]; +} diff --git a/InternalDocs/images/stack-resize-pop-push.png b/InternalDocs/images/stack-resize-pop-push.png new file mode 100644 index 0000000000000000000000000000000000000000..a739442f4acff6ed003e738ab2322388ac9419d0 GIT binary patch literal 39405 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%0D%h9KWf;r%JAW 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 b4i#_igv*hv7=qm?An(Ox#fsj2`SyPRhAnB! literal 0 HcmV?d00001 diff --git a/InternalDocs/images/stack-resize.dot b/InternalDocs/images/stack-resize.dot new file mode 100644 index 00000000000000..3f2d5a62b92f68 --- /dev/null +++ b/InternalDocs/images/stack-resize.dot @@ -0,0 +1,153 @@ +digraph stack_resize { + graph [ + fontname="Monaco", + fontsize=16, + bgcolor="white", + compound=true, + newrank=true, + splines=false + ]; + + node [ + fontname="Monaco", + fontsize=16, + shape=box, + style="rounded,filled", + color="#2563eb", + fillcolor="white", + penwidth=2, + fixedsize=true + ]; + + edge [ + color="#111111", + fontname="Monaco", + penwidth=2, + arrowsize=0.75 + ]; + + subgraph cluster_older_chunk { + label="older chunk"; + labelloc=b; + fontcolor="#0f172a"; + style="rounded,filled"; + color="#334155"; + fillcolor="#f1f5f9"; + penwidth=2; + margin=24; + + node [ + color="#64748b", + width=2.5, + ]; + + old_frame_hidden [style="invis", label=""]; + subgraph cluster_older_frames { + label=""; + penwidth=0; + old_frame_1 [label="older frame"]; + old_frame_2 [label="older frame"]; + old_frame_3 [label="older frame"]; + } + old_previous [ + color="invis", + fillcolor="invis", + width=2.15, + height=0.58, + label="previous = NULL" + ]; + + old_frame_hidden:s -> old_frame_1:n [style="invis"]; + old_frame_1:s -> old_frame_2:n; + old_frame_2:s -> old_frame_3:n; + old_frame_3:s -> old_previous:n [style="invis"]; + } + + subgraph cluster_newest_chunk { + label="newest chunk"; + labelloc=b; + fontcolor="#0f172a"; + style="rounded,filled"; + color="#1e3a8a"; + fillcolor="#eaf4ff"; + penwidth=2; + margin=24; + + top_frame [width=2.5, label="top frame"]; + newer_frame_1 [width=2.5, label="newer frame"]; + newer_frame_2 [width=2.5, label="newer frame"]; + + subgraph cluster_untouched_memory { + label=""; + color="#f59e0b"; + fillcolor="#ffec99"; + style="filled,dashed"; + penwidth=2; + margin=24; + + node [ + width=2.5, + height=0.5, + ]; + + untouched_memory_top [style="invis", label=""]; + untouched_memory [ + shape=plaintext, + style="", + fixedsize=false, + label="untouched memory\n(same size as\npreviously used)" + ]; + untouched_memory_bottom [style="invis", label=""]; + } + + new_previous [ + color="invis", + fillcolor="invis", + width=1.15, + height=0.58, + label="previous" + ]; + + top_frame:s -> newer_frame_1:n; + newer_frame_1:s -> newer_frame_2:n; + newer_frame_2:s -> untouched_memory_top:n [ + lhead=cluster_untouched_memory, + style="invis", + ]; + untouched_memory_bottom:s -> new_previous:n [ + ltail=cluster_untouched_memory, + style="invis", + ]; + } + + stack_top_label [ + shape=plaintext, + style="", + fixedsize=false, + label="stack_top", + fontcolor="#0f172a" + ]; + + { rank=same; old_frame_hidden; newer_frame_2; } + { rank=same; old_frame_1; untouched_memory_top; } + { rank=same; old_frame_2; untouched_memory; } + { rank=same; old_frame_3; untouched_memory_bottom; } + { rank=same; old_previous; new_previous; } + { rank=same; top_frame; stack_top_label; } + + top_frame -> stack_top_label [style=invis, weight=100, constraint=false]; + old_frame_1 -> newer_frame_2 [style=invis, weight=100, constraint=false]; + + newer_frame_2:w -> old_frame_1:e [ + constraint=false, + taillabel="frame chain can cross\nstack chunks", + labeldistance=15, + ]; + stack_top_label:w -> top_frame:e [ + constraint=false + ]; + new_previous:w -> old_previous:e [ + lhead=cluster_older_chunk, + constraint=false + ]; +} diff --git a/InternalDocs/images/stack-resize.png b/InternalDocs/images/stack-resize.png new file mode 100644 index 0000000000000000000000000000000000000000..93820ca6b2a6b5e8625dcc4037ddae7f1e20c405 GIT binary patch literal 68110 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
  • 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 literal 0 HcmV?d00001 From 772a834533b178e3379a12cffe3fec4a0ff61ab9 Mon Sep 17 00:00:00 2001 From: Daniele Parmeggiani Date: Fri, 8 May 2026 14:21:18 +0100 Subject: [PATCH 6/8] regen-all --- Modules/_remote_debugging/clinic/module.c.h | 3 ++- Modules/_remote_debugging/module.c | 2 +- Programs/test_frozenmain.h | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Modules/_remote_debugging/clinic/module.c.h b/Modules/_remote_debugging/clinic/module.c.h index 15df48fabb56b2..d5e5d1dc767940 100644 --- a/Modules/_remote_debugging/clinic/module.c.h +++ b/Modules/_remote_debugging/clinic/module.c.h @@ -408,6 +408,7 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_get_stats__doc__, " - frames_read_from_memory: Total frames read from remote memory\n" " - memory_reads: Total remote memory read operations\n" " - memory_bytes_read: Total bytes read from remote memory\n" +" - stack_chunks_copied: Total stack chunks copied from remote memory\n" " - code_object_cache_hits: Code object cache hits\n" " - code_object_cache_misses: Code object cache misses\n" " - stale_cache_invalidations: Times stale cache entries were cleared\n" @@ -1296,4 +1297,4 @@ _remote_debugging_is_python_process(PyObject *module, PyObject *const *args, Py_ exit: return return_value; } -/*[clinic end generated code: output=34f50b18f317b9b6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b5823b17f01cb6a6 input=a9049054013a1b77]*/ diff --git a/Modules/_remote_debugging/module.c b/Modules/_remote_debugging/module.c index ac032784e20e40..8ce3acf2ee6b8c 100644 --- a/Modules/_remote_debugging/module.c +++ b/Modules/_remote_debugging/module.c @@ -891,7 +891,7 @@ RemoteUnwinder was created with stats=True. static PyObject * _remote_debugging_RemoteUnwinder_get_stats_impl(RemoteUnwinderObject *self) -/*[clinic end generated code: output=21e36477122be2a0 input=75fef4134c12a8c9]*/ +/*[clinic end generated code: output=21e36477122be2a0 input=0e3897ce0f5b9f81]*/ { if (!self->collect_stats) { PyErr_SetString(PyExc_RuntimeError, diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 28e08e42f5c88f..1c2dbd4f6a696e 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -13,10 +13,10 @@ unsigned char M_test_frozenmain[] = { 92,2,31,0,81,5,92,6,12,0,81,6,92,5,92,6, 42,26,0,0,0,0,0,0,0,0,0,0,12,0,48,4, 50,1,0,0,0,0,0,0,29,0,74,26,0,0,9,0, - 28,0,81,1,33,0,41,8,233,0,0,0,0,78,122,18, + 28,0,81,1,33,0,41,8,233,0,0,0,0,78,218,18, 70,114,111,122,101,110,32,72,101,108,108,111,32,87,111,114, - 108,100,122,8,115,121,115,46,97,114,103,118,218,6,99,111, - 110,102,105,103,122,7,99,111,110,102,105,103,32,122,2,58, + 108,100,218,8,115,121,115,46,97,114,103,118,218,6,99,111, + 110,102,105,103,218,7,99,111,110,102,105,103,32,218,2,58, 32,41,5,218,12,112,114,111,103,114,97,109,95,110,97,109, 101,218,10,101,120,101,99,117,116,97,98,108,101,218,15,117, 115,101,95,101,110,118,105,114,111,110,109,101,110,116,218,17, @@ -25,15 +25,15 @@ unsigned char M_test_frozenmain[] = { 111,41,7,218,3,115,121,115,218,17,95,116,101,115,116,105, 110,116,101,114,110,97,108,99,97,112,105,218,5,112,114,105, 110,116,218,4,97,114,103,118,218,11,103,101,116,95,99,111, - 110,102,105,103,115,114,3,0,0,0,218,3,107,101,121,169, + 110,102,105,103,115,114,5,0,0,0,218,3,107,101,121,169, 0,243,0,0,0,0,218,18,116,101,115,116,95,102,114,111, 122,101,110,109,97,105,110,46,112,121,218,8,60,109,111,100, - 117,108,101,62,114,18,0,0,0,1,0,0,0,115,94,0, + 117,108,101,62,114,22,0,0,0,1,0,0,0,115,94,0, 0,0,241,3,1,1,1,243,8,0,1,11,219,0,24,225, 0,5,208,6,26,212,0,27,217,0,5,128,106,144,35,151, 40,145,40,212,0,27,216,9,26,215,9,38,210,9,38,211, 9,40,168,24,213,9,50,128,6,244,2,6,12,2,128,67, 241,14,0,5,10,136,71,144,67,144,53,152,2,152,54,160, 35,157,59,152,45,208,10,40,214,4,41,243,15,6,12,2, - 114,16,0,0,0, + 114,20,0,0,0, }; From 5f98e7ef2f70dd9e4392293cbc0221eb30f1cb36 Mon Sep 17 00:00:00 2001 From: Daniele Parmeggiani Date: Fri, 8 May 2026 17:43:34 +0100 Subject: [PATCH 7/8] regen-all --- Modules/_remote_debugging/clinic/module.c.h | 2 +- Programs/test_frozenmain.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Modules/_remote_debugging/clinic/module.c.h b/Modules/_remote_debugging/clinic/module.c.h index 925f0ffecb11d5..067dede2c2a73d 100644 --- a/Modules/_remote_debugging/clinic/module.c.h +++ b/Modules/_remote_debugging/clinic/module.c.h @@ -1565,4 +1565,4 @@ _remote_debugging_get_gc_stats(PyObject *module, PyObject *const *args, Py_ssize exit: return return_value; } -/*[clinic end generated code: output=36674f4cb8a653f3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b30022bf5c171170 input=a9049054013a1b77]*/ diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 1bcf98a7600851..0f07d03b05a329 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -13,10 +13,10 @@ unsigned char M_test_frozenmain[] = { 92,2,31,0,81,4,92,6,12,0,81,5,92,5,92,6, 42,26,0,0,0,0,0,0,0,0,0,0,12,0,48,4, 50,1,0,0,0,0,0,0,29,0,74,26,0,0,9,0, - 28,0,80,7,33,0,41,7,233,0,0,0,0,122,18,70, + 28,0,80,7,33,0,41,7,233,0,0,0,0,218,18,70, 114,111,122,101,110,32,72,101,108,108,111,32,87,111,114,108, - 100,122,8,115,121,115,46,97,114,103,118,218,6,99,111,110, - 102,105,103,122,7,99,111,110,102,105,103,32,122,2,58,32, + 100,218,8,115,121,115,46,97,114,103,118,218,6,99,111,110, + 102,105,103,218,7,99,111,110,102,105,103,32,218,2,58,32, 41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, 218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, 101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, @@ -25,15 +25,15 @@ unsigned char M_test_frozenmain[] = { 41,7,218,3,115,121,115,218,17,95,116,101,115,116,105,110, 116,101,114,110,97,108,99,97,112,105,218,5,112,114,105,110, 116,218,4,97,114,103,118,218,11,103,101,116,95,99,111,110, - 102,105,103,115,114,3,0,0,0,218,3,107,101,121,169,0, + 102,105,103,115,114,5,0,0,0,218,3,107,101,121,169,0, 243,0,0,0,0,218,18,116,101,115,116,95,102,114,111,122, 101,110,109,97,105,110,46,112,121,218,8,60,109,111,100,117, - 108,101,62,114,18,0,0,0,1,0,0,0,115,94,0,0, + 108,101,62,114,22,0,0,0,1,0,0,0,115,94,0,0, 0,241,3,1,1,1,243,8,0,1,11,219,0,24,225,0, 5,208,6,26,212,0,27,217,0,5,128,106,144,35,151,40, 145,40,212,0,27,216,9,26,215,9,38,210,9,38,211,9, 40,168,24,213,9,50,128,6,244,2,6,12,2,128,67,241, 14,0,5,10,136,71,144,67,144,53,152,2,152,54,160,35, 157,59,152,45,208,10,40,214,4,41,243,15,6,12,2,114, - 16,0,0,0, + 20,0,0,0, }; From 73e14570874a68322710a24636352a015e063197 Mon Sep 17 00:00:00 2001 From: Daniele Parmeggiani Date: Fri, 8 May 2026 18:17:15 +0100 Subject: [PATCH 8/8] regen-all --- Programs/test_frozenmain.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 0f07d03b05a329..1bcf98a7600851 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -13,10 +13,10 @@ unsigned char M_test_frozenmain[] = { 92,2,31,0,81,4,92,6,12,0,81,5,92,5,92,6, 42,26,0,0,0,0,0,0,0,0,0,0,12,0,48,4, 50,1,0,0,0,0,0,0,29,0,74,26,0,0,9,0, - 28,0,80,7,33,0,41,7,233,0,0,0,0,218,18,70, + 28,0,80,7,33,0,41,7,233,0,0,0,0,122,18,70, 114,111,122,101,110,32,72,101,108,108,111,32,87,111,114,108, - 100,218,8,115,121,115,46,97,114,103,118,218,6,99,111,110, - 102,105,103,218,7,99,111,110,102,105,103,32,218,2,58,32, + 100,122,8,115,121,115,46,97,114,103,118,218,6,99,111,110, + 102,105,103,122,7,99,111,110,102,105,103,32,122,2,58,32, 41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, 218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, 101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, @@ -25,15 +25,15 @@ unsigned char M_test_frozenmain[] = { 41,7,218,3,115,121,115,218,17,95,116,101,115,116,105,110, 116,101,114,110,97,108,99,97,112,105,218,5,112,114,105,110, 116,218,4,97,114,103,118,218,11,103,101,116,95,99,111,110, - 102,105,103,115,114,5,0,0,0,218,3,107,101,121,169,0, + 102,105,103,115,114,3,0,0,0,218,3,107,101,121,169,0, 243,0,0,0,0,218,18,116,101,115,116,95,102,114,111,122, 101,110,109,97,105,110,46,112,121,218,8,60,109,111,100,117, - 108,101,62,114,22,0,0,0,1,0,0,0,115,94,0,0, + 108,101,62,114,18,0,0,0,1,0,0,0,115,94,0,0, 0,241,3,1,1,1,243,8,0,1,11,219,0,24,225,0, 5,208,6,26,212,0,27,217,0,5,128,106,144,35,151,40, 145,40,212,0,27,216,9,26,215,9,38,210,9,38,211,9, 40,168,24,213,9,50,128,6,244,2,6,12,2,128,67,241, 14,0,5,10,136,71,144,67,144,53,152,2,152,54,160,35, 157,59,152,45,208,10,40,214,4,41,243,15,6,12,2,114, - 20,0,0,0, + 16,0,0,0, };