From b15d04cc1cd4f9c082a6a24b9c832b49d85968b6 Mon Sep 17 00:00:00 2001 From: cocolato Date: Tue, 20 Jan 2026 22:41:02 +0800 Subject: [PATCH 1/2] fix JIT tracer memory leak when daemon thread exits --- Lib/test/test_capi/test_opt.py | 23 +++++++++++++++++++++++ Python/pystate.c | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 79c7f530b8ae89..8cf529c6eb4439 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -3792,6 +3792,29 @@ def __next__(self): """), PYTHON_JIT="1", PYTHON_JIT_STRESS="1") self.assertEqual(result[0].rc, 0, result) + def test_144068_daemon_thread_jit_cleanup(self): + result = script_helper.run_python_until_end('-c', textwrap.dedent(""" + import threading + import time + + def hot_loop(): + end = time.time() + 5.0 + while time.time() < end: + pass + + # Create a daemon thread that will be abandoned at shutdown + t = threading.Thread(target=hot_loop, daemon=True) + t.start() + + time.sleep(0.1) + """), PYTHON_JIT="1", ASAN_OPTIONS="detect_leaks=1") + self.assertEqual(result[0].rc, 0, result) + stderr = result[0].err.decode('utf-8', errors='replace') + self.assertNotIn('LeakSanitizer', stderr, + f"Memory leak detected by ASan:\n{stderr}") + self.assertNotIn('_PyJit_TryInitializeTracing', stderr, + f"JIT tracer memory leak detected:\n{stderr}") + def global_identity(x): return x diff --git a/Python/pystate.c b/Python/pystate.c index 86dee70734a097..0993f9f906153d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1836,6 +1836,10 @@ PyThreadState_Clear(PyThreadState *tstate) _PyThreadState_ClearMimallocHeaps(tstate); +#ifdef _Py_TIER2 + _PyJit_TracerFree((_PyThreadStateImpl *)tstate); +#endif + tstate->_status.cleared = 1; // XXX Call _PyThreadStateSwap(runtime, NULL) here if "current". From ffd281a66421d554da44f98b855e52475ef6822f Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Wed, 21 Jan 2026 02:30:07 +0000 Subject: [PATCH 2/2] =?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-01-21-02-30-06.gh-issue-144068.9TTu7v.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-01-21-02-30-06.gh-issue-144068.9TTu7v.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-01-21-02-30-06.gh-issue-144068.9TTu7v.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-21-02-30-06.gh-issue-144068.9TTu7v.rst new file mode 100644 index 00000000000000..b3e5db64a368b3 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-01-21-02-30-06.gh-issue-144068.9TTu7v.rst @@ -0,0 +1 @@ +Fix JIT tracer memory leak, ensure the JIT tracer state is freed when daemon threads are cleaned up during interpreter shutdown.