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
subprocess module does not check WIFSTOPPED on SIGCHLD #73521
Comments
The attached script hits some "This should never happen" code in the subprocess module. These lines here: The root cause is a lack of checking WIFSTOPPED and WSTOPSIG in the handler. When a process elects into being ptraced via PTRACE_TRACEME, it is stopped on the SIGSEGV instead of terminating, allowing the user to attach a debugger before the kernel destroys the process. This bug makes it impossible to wait on any process which crashes, which is set up to wait for a debugger. |
To further clarify the report: When the attached proof-of-concept is executed, a RuntimeException is raised, which has a comment "Should never happen". The issue isn't due to SIGCHLD, but rather following a waitpid() call. The code attempts to suss the exit code / reason for waitpid() returning, but does not check for WIFSTOPPED in its handler. |
The attached patch should fix it. I want to incorporate a bug.py like regression test into test_subprocess.py. |
test added. |
New changeset 269296b2a047 by Gregory P. Smith in branch '3.5': New changeset ed5255a61648 by Gregory P. Smith in branch '3.6': New changeset 4f5e7d018195 by Gregory P. Smith in branch 'default': |
Among other buildbot failures: http://buildbot.python.org/all/builders/x86%20Tiger%203.6/builds/142/steps/test/logs/stdio ====================================================================== Traceback (most recent call last):
File "/Users/db3l/buildarea/3.6.bolen-tiger/build/Lib/test/test_subprocess.py", line 2514, in test_child_terminated_in_stopped_state
libc = ctypes.CDLL(libc_name)
File "/Users/db3l/buildarea/3.6.bolen-tiger/build/Lib/ctypes/__init__.py", line 348, in __init__
self._handle = _dlopen(self._name, mode)
OSError: dlopen(libc..dylib, 6): image not found Ran 260 tests in 102.297s Also, http://buildbot.python.org/all/builders/x86%20Ubuntu%20Shared%203.x/builds/240/steps/test/logs/stdio |
New changeset 8e3d412f8e89 by Gregory P. Smith in branch '2.7': |
thanks Ned, I was awaiting interesting buildbot results. :) fixed in 2.7 and 3.5 onwards. thanks for the report Zach. not closing until I also apply the fix to the subprocess32 backport. |
Of note, there's no need to actually cause a SIGSEGV to generate the signal. The tests might be more clear to replace: libc.printf(ctypes.c_char_p(0xdeadbeef)) with
|
If you want crashes, look at the portable faulthandler._sigsegv() :-) |
Neat, though that's not in the standard library. The current logic for getting a handle to libc could also be simplified via ctypes.util.find_library (https://docs.python.org/3/library/ctypes.html#finding-shared-libraries). Darwin: >>> import ctypes.util
>>> ctypes.util.find_library('c')
'/usr/lib/libc.dylib'
Linux:
>>> import ctypes.util
>>> ctypes.util.find_library('c')
'libc.so.6' |
Fixed applied to subprocess32 in google/python-subprocess32@0f1958e |
Note: 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: