(self, stack_frames, skip_idle=False)
| 88 | return filter_internal_frames(frames) |
| 89 | |
| 90 | def _iter_all_frames(self, stack_frames, skip_idle=False): |
| 91 | for interpreter_info in stack_frames: |
| 92 | for thread_info in interpreter_info.threads: |
| 93 | # skip_idle now means: skip if thread is not actively running |
| 94 | # A thread is "active" if it has the GIL OR is on CPU |
| 95 | if skip_idle: |
| 96 | status_flags = thread_info.status |
| 97 | has_gil = bool(status_flags & THREAD_STATUS_HAS_GIL) |
| 98 | on_cpu = bool(status_flags & THREAD_STATUS_ON_CPU) |
| 99 | if not (has_gil or on_cpu): |
| 100 | continue |
| 101 | frames = thread_info.frame_info |
| 102 | if frames: |
| 103 | # Filter out internal profiler frames from the bottom of the stack |
| 104 | frames = self._filter_internal_frames(frames) |
| 105 | if frames: |
| 106 | yield frames, thread_info.thread_id |
| 107 | |
| 108 | def _iter_async_frames(self, awaited_info_list): |
| 109 | # Phase 1: Index tasks and build parent relationships with pre-computed selection |
no test coverage detected