profiling.sampling incorrectly handles base_frame and native frame as the first frame
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 77.2k
- Forks
- 35.9k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
Bug description
profiling.sampling does not correctly handle some frame chains whose first frame is not a Python frame.
There are two cases:
-
The first frame is
base_frameA native thread can retain a Python thread state while waiting in C code, with no Python functions executing. Its frame chain contains only the
base_framesentinel.The sampler skips this sentinel and then raises:
RuntimeError: Failed to parse initial frame in chain -
The first frame is a native frame
When the first frame in the chain is a native frame, the sampler does not correctly handle it as the initial frame and may report the frame chain as invalid instead of adding a
<native>frame.
In both cases, the failure can cause the entire sampling call to fail, so valid Python stacks from other threads are also lost.
Reproduction
Case 1: base_frame as the first frame
Create a pthread that registers and detaches a Python thread state:
PyGILState_STATE state = PyGILState_Ensure();
PyThreadState *saved = PyEval_SaveThread();
/* Wait on a pthread condition variable while the parent samples. */
/* Cleanup after sampling. */
PyEval_RestoreThread(saved);
PyGILState_Release(state);
Keep the main thread inside a Python function and sample the child process from its parent:
unwinder = _remote_debugging.RemoteUnwinder(
pid, all_threads=True, cache_frames=False,
)
unwinder.get_stack_trace()
tachyon-empty-native-repro.zip
- Reproduces with frame caching both enabled and disabled.
Case 2: Native frame as the first frame
Construct a frame chain whose current frame is a native frame and whose previous frame leads to base_frame.
When native-frame collection is enabled, sampling this thread currently fails to correctly handle the native frame as the first frame.
Expected behavior
The sampler should correctly handle both cases:
- If the first frame is
base_frame, treat it as a valid empty Python stack. - If the first frame is a native frame, add a
<native>frame to the returned stack and continue walking the frame chain.
A special frame state in one thread should not cause the entire sampling operation to fail or prevent valid stacks from other threads from being returned.
Suspected cause
process_frame_chain() does not correctly handle cases where the first frame does not contain a parseable Python frame, including base_frame and native frames.
These cases can be incorrectly treated as a broken initial frame chain.
Environment
Linux, CPython 3.15.0rc2+dev free-threaded build and current main.
Linked PRs
- gh-157817
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.
Línea de trabajo
Comienza rastreando process_frame_chain(), centrándote en cómo maneja base_frame y un frame nativo como primer frame. Usa la reproducción proporcionada con pthread y el escenario de frame nativo para ejercitar ambos caminos. Se considera terminado cuando base_frame produce una pila de Python vacía válida, los frames nativos añaden un frame y un hilo especial no descarta las pilas válidas de otros hilos.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- c, python
- Área
- performance
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Activo
- Claridad
- Bastante claro
- Aptitud para principiantes
- 55/100