profiling.sampling incorrectly handles base_frame and native frame as the first frame
まだ誰も着手していません。
- 主要言語
- Python
- スター
- 77.2k
- フォーク
- 35.9k
- PR マージ指標
- PR 指標を取得中
説明
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
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず process_frame_chain() を追跡し、base_frame とネイティブフレームを最初のフレームとしてどのように処理するかに注目してください。提供されている pthread の再現コードとネイティブフレームのシナリオを使って、両方のパスを検証してください。base_frame が有効な空の Python スタックを生成し、ネイティブフレームが フレームを追加し、1 つの特殊なスレッドが他のスレッドの有効なスタックを破棄しなければ完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- c, python
- 領域
- performance
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 活発
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 55/100