Skip to content

Commit 6b3d3a1

Browse files
Yingming Maodkruces
authored andcommitted
offcputime: Support tracking specified processes and threads
Inspired by the perf-top command, the offcputime tool is enhanced to support tracking multiple processes and threads. $ man perf-top -p <pid>, --pid=<pid> Profile events on existing Process ID (comma separated list). -t <tid>, --tid=<tid> Profile events on existing thread ID (comma separated list). Before: $ offcputime -h optional arguments: -p PID, --pid PID trace this PID only -t TID, --tid TID trace this TID only examples: ./offcputime -p 185 # only trace threads for PID 185 ./offcputime -t 188 # only trace thread 188 After: $ offcputime -h optional arguments: -p PID, --pid PID trace these PIDs only, comma separated list -t TID, --tid TID trace these TIDs only, comma separated list examples: ./offcputime -p 185,175,165 # only trace threads for PID 185,175,165 ./offcputime -t 188,120,134 # only trace threads 188,120,134 Signed-off-by: Yingming Mao <[email protected]> Reviewed-by: Shuo Li <[email protected]>
1 parent 2718177 commit 6b3d3a1

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

tools/offcputime.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@
2323
import signal
2424

2525
# arg validation
26+
def positive_ints(val):
27+
try:
28+
ivals = [int(i) for i in val.split(',')]
29+
for i in ivals:
30+
if i < 0:
31+
raise argparse.ArgumentTypeError("must be positive ingegers")
32+
except ValueError:
33+
raise argparse.ArgumentTypeError(f"must be integers")
34+
return ivals
35+
2636
def positive_int(val):
2737
try:
2838
ival = int(val)
@@ -52,8 +62,8 @@ def stack_id_err(stack_id):
5262
./offcputime -s 5 # 5 seconds, and show symbol offsets
5363
./offcputime -m 1000 # trace only events that last more than 1000 usec
5464
./offcputime -M 10000 # trace only events that last less than 10000 usec
55-
./offcputime -p 185 # only trace threads for PID 185
56-
./offcputime -t 188 # only trace thread 188
65+
./offcputime -p 185,175,165 # only trace threads for PID 185,175,165
66+
./offcputime -t 188,120,134 # only trace threads 188,120,134
5767
./offcputime -u # only trace user threads (no kernel)
5868
./offcputime -k # only trace kernel threads (no user)
5969
./offcputime -U # only show user space stacks (no kernel)
@@ -66,10 +76,10 @@ def stack_id_err(stack_id):
6676
thread_group = parser.add_mutually_exclusive_group()
6777
# Note: this script provides --pid and --tid flags but their arguments are
6878
# referred to internally using kernel nomenclature: TGID and PID.
69-
thread_group.add_argument("-p", "--pid", metavar="PID", dest="tgid",
70-
help="trace this PID only", type=positive_int)
71-
thread_group.add_argument("-t", "--tid", metavar="TID", dest="pid",
72-
help="trace this TID only", type=positive_int)
79+
thread_group.add_argument("-p", "--pid", metavar="PID", dest="tgids",
80+
help="trace these PIDs only, comma separated list", type=positive_ints)
81+
thread_group.add_argument("-t", "--tid", metavar="TID", dest="pids",
82+
help="trace these TIDs only, comma separated list", type=positive_ints)
7383
thread_group.add_argument("-u", "--user-threads-only", action="store_true",
7484
help="user threads only (no kernel threads)")
7585
thread_group.add_argument("-k", "--kernel-threads-only", action="store_true",
@@ -200,12 +210,12 @@ def signal_ignore(signal, frame):
200210

201211
# set thread filter
202212
thread_context = ""
203-
if args.tgid is not None:
204-
thread_context = "PID %d" % args.tgid
205-
thread_filter = 'tgid == %d' % args.tgid
206-
elif args.pid is not None:
207-
thread_context = "TID %d" % args.pid
208-
thread_filter = 'pid == %d' % args.pid
213+
if args.tgids is not None:
214+
thread_context = "PIDs %s" % ','.join([str(tgid) for tgid in args.tgids])
215+
thread_filter = ' || '.join(['tgid == %d' % tgid for tgid in args.tgids])
216+
elif args.pids is not None:
217+
thread_context = "TIDs %s" % ','.join([str(pid) for pid in args.pids])
218+
thread_filter = ' || '.join(['pid == %d' % pid for pid in args.pids])
209219
elif args.user_threads_only:
210220
thread_context = "user threads"
211221
thread_filter = '!(prev->flags & PF_KTHREAD)'

0 commit comments

Comments
 (0)