https://github.com/python/cpython/commit/224b4b0ab1640db514da8639924265bac9d83134
commit: 224b4b0ab1640db514da8639924265bac9d83134
branch: main
author: Peter Bierma <[email protected]>
committer: ZeroIntensity <[email protected]>
date: 2026-10-10T11:41:34-04:00
summary:
gh-158929: Fix subinterpreter thread safety issues in `syslog` (GH-159000)
files:
A Misc/NEWS.d/next/Library/2026-10-07-20-32-20.gh-issue-158929.6dwqfQ.rst
M Lib/test/test_syslog.py
M Modules/syslogmodule.c
diff --git a/Lib/test/test_syslog.py b/Lib/test/test_syslog.py
index 54db80fa9df1afa..e6e3ccab35fa9f8 100644
--- a/Lib/test/test_syslog.py
+++ b/Lib/test/test_syslog.py
@@ -142,6 +142,29 @@ def test_subinterpreter_closelog(self):
finally:
syslog.closelog()
+ @threading_helper.requires_working_threading()
+ def test_subinterpreter_concurrent_syslog(self):
+ # gh-158929: This used to crash.
+ from concurrent import interpreters
+
+ interp = interpreters.create()
+ try:
+ def in_interpreter():
+ import syslog
+
+ for _ in range(40000):
+ try:
+ syslog.syslog('my hovercraft is full of eels')
+ except RuntimeError:
+ pass
+ thread = interp.call_in_thread(in_interpreter)
+ for i in range(40000):
+ syslog.openlog(f"python{i}")
+ syslog.closelog()
+ thread.join()
+ finally:
+ interp.close()
+
if __name__ == "__main__":
unittest.main()
diff --git
a/Misc/NEWS.d/next/Library/2026-10-07-20-32-20.gh-issue-158929.6dwqfQ.rst
b/Misc/NEWS.d/next/Library/2026-10-07-20-32-20.gh-issue-158929.6dwqfQ.rst
new file mode 100644
index 000000000000000..538db4e4c39dea3
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-10-07-20-32-20.gh-issue-158929.6dwqfQ.rst
@@ -0,0 +1,2 @@
+Fix crash when calling :func:`syslog.syslog` while a subinterpreter in
+another thread calls :func:`syslog.openlog` or :func:`syslog.closelog`.
diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c
index 2d13f9eda758ddc..cdf76cf2d1acc8b 100644
--- a/Modules/syslogmodule.c
+++ b/Modules/syslogmodule.c
@@ -69,7 +69,7 @@ module syslog
/* only one instance, only one syslog, so globals should be ok,
* these fields are writable from the main interpreter only. */
static PyObject *S_ident_o = NULL; // identifier, held by openlog()
-static char S_log_open = 0;
+static int S_log_open = 0;
static inline int
is_main_interpreter(void)
@@ -189,7 +189,7 @@ syslog_openlog_impl(PyObject *module, PyObject *ident, long
logopt,
}
openlog(ident_str, logopt, facility);
- S_log_open = 1;
+ _Py_atomic_store_int(&S_log_open, 1);
Py_XSETREF(S_ident_o, ident);
Py_RETURN_NONE;
@@ -222,7 +222,7 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int
priority,
}
/* if log is not opened, open it now */
- if (!S_log_open) {
+ if (!_Py_atomic_load_int(&S_log_open)) {
if (!is_main_interpreter()) {
PyErr_SetString(PyExc_RuntimeError, "subinterpreter can't use
syslog.syslog() "
"until the syslog is opened by
the main interpreter");
@@ -235,10 +235,6 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int
priority,
Py_DECREF(openlog_ret);
}
- /* Incref ident, because it can be decrefed if syslog.openlog() is
- * called when the GIL is released.
- */
- PyObject *ident = Py_XNewRef(S_ident_o);
#ifdef __APPLE__
// gh-98178: On macOS, libc syslog() is not thread-safe
syslog(priority, "%s", message);
@@ -247,7 +243,6 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int
priority,
syslog(priority, "%s", message);
Py_END_ALLOW_THREADS;
#endif
- Py_XDECREF(ident);
Py_RETURN_NONE;
}
@@ -273,10 +268,11 @@ syslog_closelog_impl(PyObject *module)
if (PySys_Audit("syslog.closelog", NULL) < 0) {
return NULL;
}
- if (S_log_open) {
+
+ int was_open = _Py_atomic_exchange_int(&S_log_open, 0);
+ if (was_open) {
closelog();
Py_CLEAR(S_ident_o);
- S_log_open = 0;
}
Py_RETURN_NONE;
}
_______________________________________________
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]