|
9 | 9 | from .collector import Collector, filter_internal_frames |
10 | 10 | from .opcode_utils import get_opcode_info, format_opcode |
11 | 11 | try: |
12 | | - from _remote_debugging import THREAD_STATUS_HAS_GIL, THREAD_STATUS_ON_CPU, THREAD_STATUS_UNKNOWN, THREAD_STATUS_GIL_REQUESTED, THREAD_STATUS_HAS_EXCEPTION |
| 12 | + from _remote_debugging import THREAD_STATUS_HAS_GIL, THREAD_STATUS_ON_CPU, THREAD_STATUS_UNKNOWN, THREAD_STATUS_GIL_REQUESTED, THREAD_STATUS_HAS_EXCEPTION, THREAD_STATUS_MAIN_THREAD |
13 | 13 | except ImportError: |
14 | 14 | # Fallback if module not available (shouldn't happen in normal use) |
15 | 15 | THREAD_STATUS_HAS_GIL = (1 << 0) |
16 | 16 | THREAD_STATUS_ON_CPU = (1 << 1) |
17 | 17 | THREAD_STATUS_UNKNOWN = (1 << 2) |
18 | 18 | THREAD_STATUS_GIL_REQUESTED = (1 << 3) |
19 | 19 | THREAD_STATUS_HAS_EXCEPTION = (1 << 4) |
| 20 | + THREAD_STATUS_MAIN_THREAD = (1 << 5) |
20 | 21 |
|
21 | 22 |
|
22 | 23 | # Categories matching Firefox Profiler expectations |
@@ -174,15 +175,16 @@ def collect(self, stack_frames, timestamps_us=None): |
174 | 175 | for thread_info in interpreter_info.threads: |
175 | 176 | frames = filter_internal_frames(thread_info.frame_info) |
176 | 177 | tid = thread_info.thread_id |
| 178 | + status_flags = thread_info.status |
| 179 | + is_main_thread = bool(status_flags & THREAD_STATUS_MAIN_THREAD) |
177 | 180 |
|
178 | 181 | # Initialize thread if needed |
179 | 182 | if tid not in self.threads: |
180 | | - self.threads[tid] = self._create_thread(tid) |
| 183 | + self.threads[tid] = self._create_thread(tid, is_main_thread) |
181 | 184 |
|
182 | 185 | thread_data = self.threads[tid] |
183 | 186 |
|
184 | 187 | # Decode status flags |
185 | | - status_flags = thread_info.status |
186 | 188 | has_gil = bool(status_flags & THREAD_STATUS_HAS_GIL) |
187 | 189 | on_cpu = bool(status_flags & THREAD_STATUS_ON_CPU) |
188 | 190 | gil_requested = bool(status_flags & THREAD_STATUS_GIL_REQUESTED) |
@@ -288,18 +290,12 @@ def collect(self, stack_frames, timestamps_us=None): |
288 | 290 |
|
289 | 291 | self.sample_count += len(times) |
290 | 292 |
|
291 | | - def _create_thread(self, tid): |
| 293 | + def _create_thread(self, tid, is_main_thread): |
292 | 294 | """Create a new thread structure with processed profile format.""" |
293 | 295 |
|
294 | | - # Determine if this is the main thread |
295 | | - try: |
296 | | - is_main = tid == threading.main_thread().ident |
297 | | - except (RuntimeError, AttributeError): |
298 | | - is_main = False |
299 | | - |
300 | 296 | thread = { |
301 | 297 | "name": f"Thread-{tid}", |
302 | | - "isMainThread": is_main, |
| 298 | + "isMainThread": is_main_thread, |
303 | 299 | "processStartupTime": 0, |
304 | 300 | "processShutdownTime": None, |
305 | 301 | "registerTime": 0, |
|
0 commit comments