|
25 | 25 | import ctypes |
26 | 26 | except ImportError: |
27 | 27 | ctypes = None |
| 28 | +else: |
| 29 | + import ctypes.util |
28 | 30 |
|
29 | 31 | try: |
30 | 32 | import threading |
@@ -2505,43 +2507,40 @@ def test_communicate_BrokenPipeError_stdin_close_with_timeout(self): |
2505 | 2507 | proc.communicate(timeout=999) |
2506 | 2508 | mock_proc_stdin.close.assert_called_once_with() |
2507 | 2509 |
|
2508 | | - _libc_file_extensions = { |
2509 | | - 'Linux': 'so.6', |
2510 | | - 'Darwin': 'dylib', |
2511 | | - } |
2512 | | - @unittest.skipIf(not ctypes, 'ctypes module required.') |
2513 | | - @unittest.skipIf(platform.uname()[0] not in _libc_file_extensions, |
2514 | | - 'Test requires a libc this code can load with ctypes.') |
2515 | | - @unittest.skipIf(not sys.executable, 'Test requires sys.executable.') |
| 2510 | + @unittest.skipIf(not ctypes, 'ctypes module required') |
| 2511 | + @unittest.skipIf(not sys.executable, 'Test requires sys.executable') |
2516 | 2512 | def test_child_terminated_in_stopped_state(self): |
2517 | 2513 | """Test wait() behavior when waitpid returns WIFSTOPPED; issue29335.""" |
2518 | 2514 | PTRACE_TRACEME = 0 # From glibc and MacOS (PT_TRACE_ME). |
2519 | | - libc_name = 'libc.' + self._libc_file_extensions[platform.uname()[0]] |
| 2515 | + libc_name = ctypes.util.find_library('c') |
2520 | 2516 | libc = ctypes.CDLL(libc_name) |
2521 | 2517 | if not hasattr(libc, 'ptrace'): |
2522 | | - raise unittest.SkipTest('ptrace() required.') |
2523 | | - test_ptrace = subprocess.Popen( |
2524 | | - [sys.executable, '-c', """if True: |
2525 | | - import ctypes |
2526 | | - libc = ctypes.CDLL({libc_name!r}) |
2527 | | - libc.ptrace({PTRACE_TRACEME}, 0, 0) |
2528 | | - """.format(libc_name=libc_name, PTRACE_TRACEME=PTRACE_TRACEME) |
2529 | | - ]) |
2530 | | - if test_ptrace.wait() != 0: |
2531 | | - raise unittest.SkipTest('ptrace() failed - unable to test.') |
2532 | | - child = subprocess.Popen( |
2533 | | - [sys.executable, '-c', """if True: |
| 2518 | + raise unittest.SkipTest('ptrace() required') |
| 2519 | + |
| 2520 | + code = textwrap.dedent(""" |
2534 | 2521 | import ctypes |
| 2522 | + import faulthandler |
| 2523 | + from test.support import SuppressCrashReport |
| 2524 | +
|
2535 | 2525 | libc = ctypes.CDLL({libc_name!r}) |
2536 | 2526 | libc.ptrace({PTRACE_TRACEME}, 0, 0) |
2537 | | - libc.printf(ctypes.c_char_p(0xdeadbeef)) # Crash the process. |
2538 | | - """.format(libc_name=libc_name, PTRACE_TRACEME=PTRACE_TRACEME) |
2539 | | - ]) |
| 2527 | + """.format(libc_name=libc_name, PTRACE_TRACEME=PTRACE_TRACEME)) |
| 2528 | + |
| 2529 | + child = subprocess.Popen([sys.executable, '-c', code]) |
| 2530 | + if child.wait() != 0: |
| 2531 | + raise unittest.SkipTest('ptrace() failed - unable to test') |
| 2532 | + |
| 2533 | + code += textwrap.dedent(""" |
| 2534 | + with SuppressCrashReport(): |
| 2535 | + # Crash the process |
| 2536 | + faulthandler._sigsegv() |
| 2537 | + """) |
| 2538 | + child = subprocess.Popen([sys.executable, '-c', code]) |
2540 | 2539 | try: |
2541 | 2540 | returncode = child.wait() |
2542 | | - except Exception as e: |
| 2541 | + except: |
2543 | 2542 | child.kill() # Clean up the hung stopped process. |
2544 | | - raise e |
| 2543 | + raise |
2545 | 2544 | self.assertNotEqual(0, returncode) |
2546 | 2545 | self.assertLess(returncode, 0) # signal death, likely SIGSEGV. |
2547 | 2546 |
|
|
0 commit comments