https://github.com/python/cpython/commit/29840247ff6da36808cd04115421ff59cdaea455
commit: 29840247ff6da36808cd04115421ff59cdaea455
branch: main
author: Hai Zhu <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2026-01-24T09:43:01Z
summary:
gh-144068: fix JIT tracer memory leak when daemon thread exits (GH-144077)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-01-21-02-30-06.gh-issue-144068.9TTu7v.rst
M Lib/test/test_capi/test_opt.py
M Python/pystate.c
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index da0d4078c9f5ed..f224984777500a 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -3889,6 +3889,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/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.
diff --git a/Python/pystate.c b/Python/pystate.c
index 19f1245d60a2f8..a8f37bedc81247 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1843,6 +1843,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".
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]