Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions tools/lib/ustat.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import sys
from subprocess import call
from time import sleep, strftime
import signal

class Category(object):
THREAD = "THREAD"
Expand Down Expand Up @@ -242,10 +243,17 @@ def _detach_probes(self):
self.bpf.cleanup() # Cleans up all attached probes
self.bpf = None

def _sigint_handler(self, signum, frame):
self.exiting = True;
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.exiting = True; ends with a semicolon, which triggers pycodestyle E703 (and scripts/py-style-check.sh runs pycodestyle over tools/**/*.py). Remove the trailing semicolon to avoid CI/style check failures.

Suggested change
self.exiting = True;
self.exiting = True

Copilot uses AI. Check for mistakes.
if self.in_sleep:
raise KeyboardInterrupt
Comment on lines +246 to +249
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_sigint_handler reads self.in_sleep, but in_sleep is only set inside _loop_iter. If SIGINT arrives before the first iteration (or between iterations), this will raise AttributeError from inside the signal handler. Initialize self.in_sleep = False before installing the handler (e.g., in run()), or use getattr(self, 'in_sleep', False) in the handler.

Copilot uses AI. Check for mistakes.

def _loop_iter(self):
self._attach_probes()
try:
self.in_sleep = True
sleep(self.args.interval)
self.in_sleep = False
Comment on lines 251 to +256
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the custom SIGINT handler, SIGINT received outside the sleep() window (e.g., during _attach_probes() or printing) sets self.exiting = True but _loop_iter() will still call sleep(self.args.interval) on that iteration. Consider checking self.exiting before sleeping so Ctrl-C exits promptly when possible (while still allowing cleanup to run).

Copilot uses AI. Check for mistakes.
except KeyboardInterrupt:
self.exiting = True
Comment on lines +256 to 258
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If sleep() is interrupted, execution jumps to the except KeyboardInterrupt block and self.in_sleep stays True. That can cause later SIGINTs (e.g., during detach/cleanup) to incorrectly raise KeyboardInterrupt, reintroducing the cleanup failure this PR is trying to avoid. Ensure self.in_sleep is always reset (e.g., move it into a finally block).

Suggested change
self.in_sleep = False
except KeyboardInterrupt:
self.exiting = True
except KeyboardInterrupt:
self.exiting = True
finally:
self.in_sleep = False

Copilot uses AI. Check for mistakes.

Expand Down Expand Up @@ -293,6 +301,7 @@ def run(self):
self.args.interval)
countdown = self.args.count
self.exiting = False
signal.signal(signal.SIGINT, self._sigint_handler)
while True:
self._loop_iter()
countdown -= 1
Expand Down
Loading