|
14 | 14 | from .stack_collector import CollapsedStackCollector |
15 | 15 |
|
16 | 16 | FREE_THREADED_BUILD = sysconfig.get_config_var("Py_GIL_DISABLED") is not None |
| 17 | +MAX_STARTUP_ATTEMPTS = 5 |
| 18 | +STARTUP_RETRY_DELAY_SECONDS = 0.1 |
| 19 | + |
17 | 20 |
|
18 | 21 | class SampleProfiler: |
19 | 22 | def __init__(self, pid, sample_interval_usec, all_threads): |
@@ -538,6 +541,30 @@ def _validate_collapsed_format_args(args, parser): |
538 | 541 | args.outfile = f"collapsed.{args.pid}.txt" |
539 | 542 |
|
540 | 543 |
|
| 544 | +def wait_for_process_and_sample(process_pid, sort_value, args): |
| 545 | + for attempt in range(MAX_STARTUP_ATTEMPTS): |
| 546 | + try: |
| 547 | + sample( |
| 548 | + process_pid, |
| 549 | + sort=sort_value, |
| 550 | + sample_interval_usec=args.interval, |
| 551 | + duration_sec=args.duration, |
| 552 | + filename=args.outfile, |
| 553 | + all_threads=args.all_threads, |
| 554 | + limit=args.limit, |
| 555 | + show_summary=not args.no_summary, |
| 556 | + output_format=args.format, |
| 557 | + realtime_stats=args.realtime_stats, |
| 558 | + ) |
| 559 | + break |
| 560 | + except RuntimeError: |
| 561 | + if attempt < MAX_STARTUP_ATTEMPTS - 1: |
| 562 | + print("Waiting for process to start...") |
| 563 | + time.sleep(STARTUP_RETRY_DELAY_SECONDS) |
| 564 | + else: |
| 565 | + raise RuntimeError("Process failed to start after maximum retries") |
| 566 | + |
| 567 | + |
541 | 568 | def main(): |
542 | 569 | # Create the main parser |
543 | 570 | parser = argparse.ArgumentParser( |
@@ -760,24 +787,7 @@ def main(): |
760 | 787 | process = subprocess.Popen(cmd) |
761 | 788 |
|
762 | 789 | try: |
763 | | - exit_code = process.wait(timeout=0.1) |
764 | | - sys.exit(exit_code) |
765 | | - except subprocess.TimeoutExpired: |
766 | | - pass |
767 | | - |
768 | | - try: |
769 | | - sample( |
770 | | - process.pid, |
771 | | - sort=sort_value, |
772 | | - sample_interval_usec=args.interval, |
773 | | - duration_sec=args.duration, |
774 | | - filename=args.outfile, |
775 | | - all_threads=args.all_threads, |
776 | | - limit=args.limit, |
777 | | - show_summary=not args.no_summary, |
778 | | - output_format=args.format, |
779 | | - realtime_stats=args.realtime_stats, |
780 | | - ) |
| 790 | + wait_for_process_and_sample(process.pid, sort_value, args) |
781 | 791 | finally: |
782 | 792 | if process.poll() is None: |
783 | 793 | process.terminate() |
|
0 commit comments