`test_is_python_process_non_python_subprocess` always times out when `sleep` is a multicall binary (Alpine/BusyBox, RHEL UBI9)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 76/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- linux, python
- Área
- operating-systems, testing
Línea de trabajo
Lee Lib/test/test_profiling/test_sampling_profiler/test_children.py, especialmente _wait_for_process_exec() y test_is_python_process_non_python_subprocess. El issue incluye una comprobación propuesta que detecta cuándo cambia el ejecutable del proceso hijo, independientemente de su nombre. Actualiza el helper y el lugar donde se llama y, después, ejecuta el test indicado en Linux; debería pasar tanto con binarios sleep multicall como con binarios normales.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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_importfails. - 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
- Lenguaje dominante
- Python
- Estrellas
- 77.8k
- Forks
- 37.7k
- Merge medio
- 11 h 25 min
- PR fusionados (30 d)
- 723
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de python/cpython
-
Null dereferencing of a pointer in initconfig.cPosiblemente ocupada @lazerg la tomó hoy. Abiertointerpreter-core topic-C-API type-bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
python/cpython#160962 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
-
3.16 build pending type-bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
python/cpython#160829 · 5 comentarios ·
Los mantenedores suelen responder en 1 día
-
dependencies infra topic-ensurepip
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
Los mantenedores suelen responder en 1 día
-
symtable: repr() of a Symbol raises TypeError under -X lazy_imports=allPosiblemente ocupada @anistark la tomó hace 1 día. Abiertostdlib topic-lazy-imports type-bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
python/cpython#160810 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
-
tarfile: extractfile(member).read() of a sparse member is slow due to repeated bytes concatenationPosiblemente ocupada @devdavidejesus la tomó hace 1 día. Abiertoperformance stdlib triaged type-bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
python/cpython#160774 · 2 comentarios · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de python/cpython
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
vllm-project/vllm#64845 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
dekobon/big-code-analysis#1729 ·
Los mantenedores suelen responder en 1 día
-
Add `openai_safety_identifier`, the replacement for the `user` field that `openai_user` sendsAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
pydantic/pydantic-ai#12091 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100