-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible race condition between signal catching and signal.signal #87572
Comments
We can receive signals (at the C level, in trip_signal() in signalmodule.c) while signal.signal is being called to modify the corresponding handler. Later when PyErr_CheckSignals() is called to handle the given signal, the handler may be a non-callable object and will raise a cryptic asynchronous exception. |
Here is a reproducer: If you execute it, it will fail after a few iterations: sig 2
sig 2
sig 2
Traceback (most recent call last):
File "/home/antoine/cpython/default/setinterrupt.py", line 30, in <module>
main()
File "/home/antoine/cpython/default/setinterrupt.py", line 27, in main
cycle_handlers(signum)
File "/home/antoine/cpython/default/setinterrupt.py", line 19, in cycle_handlers
signal.signal(signum, handler)
File "/home/antoine/cpython/default/Lib/signal.py", line 48, in signal
return _int_to_enum(handler, Handlers)
File "/home/antoine/cpython/default/Lib/signal.py", line 30, in _int_to_enum
return enum_klass(value)
File "/home/antoine/cpython/default/Lib/enum.py", line 606, in __call__
return cls.__new__(cls, value)
File "/home/antoine/cpython/default/Lib/enum.py", line 927, in __new__
ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__))
TypeError: 'int' object is not callable |
The change added a new functional test. As I expected, it failed on "AMD64 Debian root". I expected it because the previously added functional test failed failed on "AMD64 Debian root", I reported the race condition in 2017 and it's still not fixed: bpo-30849. The new functional test has two race conditions. I reopen the issue. == Race condition 1 == AMD64 Debian root 3.x: 0:15:05 load avg: 2.58 [137/427/1] test_signal failed (env changed) (1 min 13 sec)
Warning -- Unraisable exception
Traceback (most recent call last):
File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/threading.py", line 1067, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
OSError: Signal 10 ignored due to race condition == Race condition 2 == By the way, the test also fails when I stress my laptop: $ ./python -m test --fail-env-changed test_signal -F -j40 -m test_stress_modifying_handlers -v
== CPython 3.10.0a6+ (heads/master:a9c03d7fb7, Mar 10 2021, 12:41:26) [GCC 10.2.1 20201125 (Red Hat 10.2.1-9)]
== Linux-5.10.15-200.fc33.x86_64-x86_64-with-glibc2.32 little-endian
== cwd: /home/vstinner/python/master/build/test_python_223315æ
== CPU count: 8
== encodings: locale=UTF-8, FS=utf-8
0:00:00 load avg: 4.17 Run tests in parallel using 40 child processes
(...)
0:00:05 load avg: 7.52 [ 5/1] test_signal failed
test_stress_modifying_handlers (test.test_signal.StressTest) ... FAIL ====================================================================== Traceback (most recent call last):
File "/home/vstinner/python/master/Lib/test/test_signal.py", line 1297, in test_stress_modifying_handlers
self.assertGreater(num_received_signals, 0)
AssertionError: 0 not greater than 0 Ran 1 test in 0.039s FAILED (failures=1) |
I don't think that it's a bug in Python, but more race conditions in the test. |
PyErr_CheckSignals
tries to execute a non-Python signal handler #24756PyErr_CheckSignals
tries to execute a non-Python signal handler (GH-24756) #24761PyErr_CheckSignals
tries to execute a non-Python signal handler (GH-24756) #24762Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: