Sample a process in live/interactive mode with curses TUI. Args: pid: Process ID to sample collector: LiveStatsCollector instance duration_sec: How long to sample for (seconds) all_threads: Whether to sample all threads realtime_stats: Whether to print re
(
pid,
collector,
*,
duration_sec=None,
all_threads=False,
realtime_stats=False,
mode=PROFILING_MODE_WALL,
async_aware=None,
native=False,
gc=True,
opcodes=False,
blocking=False,
)
| 437 | |
| 438 | |
| 439 | def sample_live( |
| 440 | pid, |
| 441 | collector, |
| 442 | *, |
| 443 | duration_sec=None, |
| 444 | all_threads=False, |
| 445 | realtime_stats=False, |
| 446 | mode=PROFILING_MODE_WALL, |
| 447 | async_aware=None, |
| 448 | native=False, |
| 449 | gc=True, |
| 450 | opcodes=False, |
| 451 | blocking=False, |
| 452 | ): |
| 453 | """Sample a process in live/interactive mode with curses TUI. |
| 454 | |
| 455 | Args: |
| 456 | pid: Process ID to sample |
| 457 | collector: LiveStatsCollector instance |
| 458 | duration_sec: How long to sample for (seconds) |
| 459 | all_threads: Whether to sample all threads |
| 460 | realtime_stats: Whether to print real-time sampling statistics |
| 461 | mode: Profiling mode - WALL (all samples), CPU (only when on CPU), |
| 462 | GIL (only when holding GIL), ALL (includes GIL and CPU status), |
| 463 | EXCEPTION (only when thread has an active exception) |
| 464 | native: Whether to include native frames |
| 465 | gc: Whether to include GC frames |
| 466 | opcodes: Whether to include opcode information |
| 467 | blocking: Whether to stop all threads before sampling for consistent snapshots |
| 468 | |
| 469 | Returns: |
| 470 | The collector with collected samples |
| 471 | """ |
| 472 | import curses |
| 473 | |
| 474 | # Check if process is alive before doing any heavy initialization |
| 475 | if not _is_process_running(pid): |
| 476 | print(f"No samples collected - process {pid} exited before profiling could begin.", file=sys.stderr) |
| 477 | return collector |
| 478 | |
| 479 | # Get sample interval from collector |
| 480 | sample_interval_usec = collector.sample_interval_usec |
| 481 | |
| 482 | # PROFILING_MODE_ALL implies no skipping at all |
| 483 | if mode == PROFILING_MODE_ALL: |
| 484 | skip_non_matching_threads = False |
| 485 | else: |
| 486 | skip_non_matching_threads = True |
| 487 | |
| 488 | profiler = SampleProfiler( |
| 489 | pid, |
| 490 | sample_interval_usec, |
| 491 | all_threads=all_threads, |
| 492 | mode=mode, |
| 493 | native=native, |
| 494 | gc=gc, |
| 495 | opcodes=opcodes, |
| 496 | skip_non_matching_threads=skip_non_matching_threads, |
no test coverage detected
searching dependent graphs…