profiling.sampling incorrectly handles base_frame and native frame as the first frame
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 35.9k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
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
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu bằng cách lần theo process_frame_chain(), tập trung vào cách nó xử lý base_frame và một native frame khi là frame đầu tiên. Sử dụng bản tái hiện pthread được cung cấp và kịch bản native-frame để kiểm tra cả hai nhánh. Được xem là hoàn tất khi base_frame tạo ra một Python stack rỗng hợp lệ, các native frame thêm một frame , và một thread đặc biệt không loại bỏ các stack hợp lệ từ những thread khác.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- c, python
- Lĩnh vực
- performance
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Sôi nổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 55/100