Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

`test_is_python_process_non_python_subprocess` always times out when `sleep` is a multicall binary (Alpine/BusyBox, RHEL UBI9)

Đang mở Phù hợp với người mới
#160,881 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
76/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
linux, python
Lĩnh vực
operating-systems, testing

Hướng nghiên cứu

Đọc Lib/test/test_profiling/test_sampling_profiler/test_children.py, đặc biệt là _wait_for_process_exec() và test_is_python_process_non_python_subprocess. Issue có đề xuất một bước kiểm tra phát hiện khi executable của tiến trình con thay đổi, bất kể tên của nó. Cập nhật helper và vị trí gọi helper, sau đó chạy test được nêu trên Linux; test cần thành công với cả các binary sleep multicall lẫn các binary thông thường.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

tests topic-profiling type-bug
Bug report
Bug description:

The fix for gh-159534 (GH-160028, backported to 3.15 in GH-160080) makes test_is_python_process_non_python_subprocess fail every time on systems where sleep is provided by a multicall binary. That includes the Alpine buildbots, where the original gh-159534 failure was found:

FAIL: test_is_python_process_non_python_subprocess (test.test_profiling.test_sampling_profiler.test_children.TestIsPythonProcess.test_is_python_process_non_python_subprocess)
Test that a non-Python subprocess is not detected as Python.
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".../Lib/test/test_profiling/test_sampling_profiler/test_children.py", line 628, in test_is_python_process_non_python_subprocess
    _wait_for_process_exec(proc, "sleep", SHORT_TIMEOUT)
  File ".../Lib/test/test_profiling/test_sampling_profiler/test_children.py", line 91, in _wait_for_process_exec
    for _ in sleeping_retry(timeout, max_delay=0.1):
  File ".../Lib/test/support/__init__.py", line 2779, in sleeping_retry
    for _ in busy_retry(timeout, err_msg, error=error):
  File ".../Lib/test/support/__init__.py", line 2749, in busy_retry
    raise AssertionError(msg)
AssertionError: timeout (45.1 seconds)
Buildbots

AMD64 Alpine Linux NoGIL 3.x:

  • build 3444 (before GH-160028): the original intermittent failure, True is not false.
  • build 3445 (first build with GH-160028): timeout (45.1 seconds). Every build since fails the same way, e.g. build 3523.

AMD64 Alpine Linux 3.15:

  • build 800 (before GH-160080): only test_lazy_import fails.
  • build 815 (first build with GH-160080) and every build since, including build 851 just before v3.15.2 was tagged: this test fails too.

This failure is separate from the test_lazy_import crash on Alpine (gh-159535). The Alpine builders will stay red after that crash is fixed.

Cause

The new _wait_for_process_exec() helper waits until os.path.basename(os.readlink(f"/proc/{pid}/exe")) == "sleep". When sleep is a multicall binary, /proc/{pid}/exe points to the multicall binary instead:

System /usr/bin/sleep or /bin/sleep /proc/{pid}/exe of a running sleep
Alpine 3.24 (BusyBox) symlink to /bin/busybox /bin/busybox
RHEL UBI9 (coreutils-single, the image default) shebang script #!/usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/coreutils
RHEL UBI9 after dnf swap coreutils-single coreutils regular binary /usr/bin/sleep

The condition never becomes true, so the test always times out.

Reproducer, tested in python:3-alpine and registry.access.redhat.com/ubi9/ubi:

import os, subprocess, time
proc = subprocess.Popen(["sleep", "10"])
time.sleep(0.5)
print(os.readlink(f"/proc/{proc.pid}/exe"))
proc.kill()
Suggested fix

The helper only needs to know that the child has called exec(). The program name doesn't matter. Before exec(), the forked child's /proc/{pid}/exe is the parent's Python executable, so wait until it differs from the parent's:

-def _wait_for_process_exec(proc, name, timeout):
+def _wait_for_process_exec(proc, timeout):
     # Wait until a child process calls exec() to replace the forked process
-    # executable. Raise AssertionError on timeout.
+    # executable. Don't check the executable name: it can be a multicall
+    # binary such as /bin/busybox. Raise AssertionError on timeout.
+    parent_exe = os.readlink("/proc/self/exe")
     for _ in sleeping_retry(timeout, max_delay=0.1):
         exe = os.readlink(f"/proc/{proc.pid}/exe")
-        if os.path.basename(exe) == name:
+        if exe != parent_exe:
             break
-            _wait_for_process_exec(proc, "sleep", SHORT_TIMEOUT)
+            _wait_for_process_exec(proc, SHORT_TIMEOUT)

I tested this check with the reproducer on Alpine (BusyBox) and on UBI9 with both coreutils-single and coreutils. It detects the exec() in all three cases, while the current name check fails on Alpine and on UBI9 with coreutils-single.

CPython versions tested on:

3.15.2, CPython main branch

Operating systems tested on:

Linux (Alpine 3.24 buildbots, RHEL UBI9 container)

CPython versions tested on:

3.15

Operating systems tested on:

Linux

Linked PRs
  • gh-160901
Ngôn ngữ chính
Python
Star
77.8k
Fork
37.7k
Merge trung bình
11 giờ 25 phút
Pull request đã merge (30 ngày)
723

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của python/cpython

Tất cả issue của python/cpython

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.