profiling.sampling incorrectly handles base_frame and native frame as the first frame

Aperta
#157,605 8 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
55/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
c, python
Ambito
performance

Direzione di ricerca

Inizia tracciando process_frame_chain(), concentrandoti su come gestisce base_frame e un frame nativo come primo frame. Usa la riproduzione pthread fornita e lo scenario con frame nativo per esercitare entrambi i percorsi. Il lavoro è completato quando base_frame produce uno stack Python vuoto valido, i frame nativi aggiungono un frame e un thread speciale non scarta gli stack validi degli altri thread.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

extension-modules topic-profiling type-bug

Bug description

profiling.sampling does not correctly handle some frame chains whose first frame is not a Python frame.

There are two cases:

  1. The first frame is base_frame

    A 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_frame sentinel.

    The sampler skips this sentinel and then raises:

    RuntimeError: Failed to parse initial frame in chain

  2. 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:

  1. If the first frame is base_frame, treat it as a valid empty Python stack.
  2. 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
Lingua principale
Python
Stelle
77.2k
Fork
36k
Merge medio
1g 9h
PR unite (30g)
558

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di python/cpython

Tutte le issue di python/cpython

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.