From 86df1af543ad05708a5f879d99032b9c1741e24c Mon Sep 17 00:00:00 2001 From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Wed, 8 Mar 2023 13:29:39 +0530 Subject: [PATCH] GH-102397: Fix segfault from race condition in signal handling (GH-102399) (cherry picked from commit 1a84cc007e207f2dd61f86a7fc3d86632fdce72f) Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Co-authored-by: Gregory P. Smith --- Lib/test/test_signal.py | 15 +++++++++++++++ ...2023-03-04-06-48-34.gh-issue-102397.ACJaOf.rst | 2 ++ Modules/signalmodule.c | 4 ++++ 3 files changed, 21 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-03-04-06-48-34.gh-issue-102397.ACJaOf.rst diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index c2b5861fc3e9ca..294cf3888d112c 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -1349,6 +1349,21 @@ def handler(a, b): signal.raise_signal(signal.SIGINT) self.assertTrue(is_ok) + def test__thread_interrupt_main(self): + # See https://github.com/python/cpython/issues/102397 + code = """if 1: + import _thread + class Foo(): + def __del__(self): + _thread.interrupt_main() + + x = Foo() + """ + + rc, out, err = assert_python_ok('-c', code) + self.assertIn(b'OSError: Signal 2 ignored due to race condition', err) + + class PidfdSignalTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-03-04-06-48-34.gh-issue-102397.ACJaOf.rst b/Misc/NEWS.d/next/Core and Builtins/2023-03-04-06-48-34.gh-issue-102397.ACJaOf.rst new file mode 100644 index 00000000000000..db0b3f32c2ec0b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-03-04-06-48-34.gh-issue-102397.ACJaOf.rst @@ -0,0 +1,2 @@ +Fix segfault from race condition in signal handling during garbage collection. +Patch by Kumar Aditya. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 80fa4d50eef714..bcfd5537708da9 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -177,6 +177,10 @@ get_signal_state(PyObject *module) static inline int compare_handler(PyObject *func, PyObject *dfl_ign_handler) { + // See https://github.com/python/cpython/pull/102399 + if (func == NULL || dfl_ign_handler == NULL) { + return 0; + } assert(PyLong_CheckExact(dfl_ign_handler)); if (!PyLong_CheckExact(func)) { return 0;