Skip to content

Commit 8857c77

Browse files
committed
fix: handle KeyboardInterrupt when sampling and print the result
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
1 parent bc9e63d commit 8857c77

2 files changed

Lines changed: 48 additions & 41 deletions

File tree

Lib/profiling/sampling/sample.py

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -56,50 +56,56 @@ def sample(self, collector, duration_sec=10):
5656
last_sample_time = start_time
5757
realtime_update_interval = 1.0 # Update every second
5858
last_realtime_update = start_time
59+
interrupted = False
5960

60-
while running_time < duration_sec:
61-
# Check if live collector wants to stop
62-
if hasattr(collector, 'running') and not collector.running:
63-
break
64-
65-
current_time = time.perf_counter()
66-
if next_time < current_time:
67-
try:
68-
stack_frames = self.unwinder.get_stack_trace()
69-
collector.collect(stack_frames)
70-
except ProcessLookupError:
71-
duration_sec = current_time - start_time
61+
try:
62+
while running_time < duration_sec:
63+
# Check if live collector wants to stop
64+
if hasattr(collector, 'running') and not collector.running:
7265
break
73-
except (RuntimeError, UnicodeDecodeError, MemoryError, OSError):
74-
collector.collect_failed_sample()
75-
errors += 1
76-
except Exception as e:
77-
if not self._is_process_running():
78-
break
79-
raise e from None
80-
81-
# Track actual sampling intervals for real-time stats
82-
if num_samples > 0:
83-
actual_interval = current_time - last_sample_time
84-
self.sample_intervals.append(
85-
1.0 / actual_interval
86-
) # Convert to Hz
87-
self.total_samples += 1
88-
89-
# Print real-time statistics if enabled
90-
if (
91-
self.realtime_stats
92-
and (current_time - last_realtime_update)
93-
>= realtime_update_interval
94-
):
95-
self._print_realtime_stats()
96-
last_realtime_update = current_time
97-
98-
last_sample_time = current_time
99-
num_samples += 1
100-
next_time += sample_interval_sec
10166

67+
current_time = time.perf_counter()
68+
if next_time < current_time:
69+
try:
70+
stack_frames = self.unwinder.get_stack_trace()
71+
collector.collect(stack_frames)
72+
except ProcessLookupError:
73+
duration_sec = current_time - start_time
74+
break
75+
except (RuntimeError, UnicodeDecodeError, MemoryError, OSError):
76+
collector.collect_failed_sample()
77+
errors += 1
78+
except Exception as e:
79+
if not self._is_process_running():
80+
break
81+
raise e from None
82+
83+
# Track actual sampling intervals for real-time stats
84+
if num_samples > 0:
85+
actual_interval = current_time - last_sample_time
86+
self.sample_intervals.append(
87+
1.0 / actual_interval
88+
) # Convert to Hz
89+
self.total_samples += 1
90+
91+
# Print real-time statistics if enabled
92+
if (
93+
self.realtime_stats
94+
and (current_time - last_realtime_update)
95+
>= realtime_update_interval
96+
):
97+
self._print_realtime_stats()
98+
last_realtime_update = current_time
99+
100+
last_sample_time = current_time
101+
num_samples += 1
102+
next_time += sample_interval_sec
103+
104+
running_time = time.perf_counter() - start_time
105+
except KeyboardInterrupt:
106+
interrupted = True
102107
running_time = time.perf_counter() - start_time
108+
print("Interrupted by user.")
103109

104110
# Clear real-time stats line if it was being displayed
105111
if self.realtime_stats and len(self.sample_intervals) > 0:
@@ -120,7 +126,7 @@ def sample(self, collector, duration_sec=10):
120126
collector.set_stats(self.sample_interval_usec, running_time, sample_rate, error_rate)
121127

122128
expected_samples = int(duration_sec / sample_interval_sec)
123-
if num_samples < expected_samples and not is_live_mode:
129+
if num_samples < expected_samples and not is_live_mode and not interrupted:
124130
print(
125131
f"Warning: missed {expected_samples - num_samples} samples "
126132
f"from the expected total of {expected_samples} "
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix: handle KeyboardInterrupt when sampling and print the result.

0 commit comments

Comments
 (0)