xref: /aosp_15_r20/external/bcc/tools/syscount.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python
2*387f9dfdSAndroid Build Coastguard Worker#
3*387f9dfdSAndroid Build Coastguard Worker# syscount   Summarize syscall counts and latencies.
4*387f9dfdSAndroid Build Coastguard Worker#
5*387f9dfdSAndroid Build Coastguard Worker# USAGE: syscount [-h] [-p PID] [-t TID] [-i INTERVAL] [-d DURATION] [-T TOP]
6*387f9dfdSAndroid Build Coastguard Worker#                 [-x] [-e ERRNO] [-L] [-m] [-P] [-l] [--syscall SYSCALL]
7*387f9dfdSAndroid Build Coastguard Worker#
8*387f9dfdSAndroid Build Coastguard Worker# Copyright 2017, Sasha Goldshtein.
9*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
10*387f9dfdSAndroid Build Coastguard Worker#
11*387f9dfdSAndroid Build Coastguard Worker# 15-Feb-2017   Sasha Goldshtein    Created this.
12*387f9dfdSAndroid Build Coastguard Worker# 16-May-2022   Rocky Xing          Added TID filter support.
13*387f9dfdSAndroid Build Coastguard Worker# 26-Jul-2022   Rocky Xing          Added syscall filter support.
14*387f9dfdSAndroid Build Coastguard Worker
15*387f9dfdSAndroid Build Coastguard Workerfrom time import sleep, strftime
16*387f9dfdSAndroid Build Coastguard Workerimport argparse
17*387f9dfdSAndroid Build Coastguard Workerimport errno
18*387f9dfdSAndroid Build Coastguard Workerimport itertools
19*387f9dfdSAndroid Build Coastguard Workerimport sys
20*387f9dfdSAndroid Build Coastguard Workerimport signal
21*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
22*387f9dfdSAndroid Build Coastguard Workerfrom bcc.utils import printb
23*387f9dfdSAndroid Build Coastguard Workerfrom bcc.syscall import syscall_name, syscalls
24*387f9dfdSAndroid Build Coastguard Worker
25*387f9dfdSAndroid Build Coastguard Workerif sys.version_info.major < 3:
26*387f9dfdSAndroid Build Coastguard Worker    izip_longest = itertools.izip_longest
27*387f9dfdSAndroid Build Coastguard Workerelse:
28*387f9dfdSAndroid Build Coastguard Worker    izip_longest = itertools.zip_longest
29*387f9dfdSAndroid Build Coastguard Worker
30*387f9dfdSAndroid Build Coastguard Worker# signal handler
31*387f9dfdSAndroid Build Coastguard Workerdef signal_ignore(signal, frame):
32*387f9dfdSAndroid Build Coastguard Worker    print()
33*387f9dfdSAndroid Build Coastguard Worker
34*387f9dfdSAndroid Build Coastguard Workerdef handle_errno(errstr):
35*387f9dfdSAndroid Build Coastguard Worker    try:
36*387f9dfdSAndroid Build Coastguard Worker        return abs(int(errstr))
37*387f9dfdSAndroid Build Coastguard Worker    except ValueError:
38*387f9dfdSAndroid Build Coastguard Worker        pass
39*387f9dfdSAndroid Build Coastguard Worker
40*387f9dfdSAndroid Build Coastguard Worker    try:
41*387f9dfdSAndroid Build Coastguard Worker        return getattr(errno, errstr)
42*387f9dfdSAndroid Build Coastguard Worker    except AttributeError:
43*387f9dfdSAndroid Build Coastguard Worker        raise argparse.ArgumentTypeError("couldn't map %s to an errno" % errstr)
44*387f9dfdSAndroid Build Coastguard Worker
45*387f9dfdSAndroid Build Coastguard Worker
46*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(
47*387f9dfdSAndroid Build Coastguard Worker    description="Summarize syscall counts and latencies.")
48*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid", type=int,
49*387f9dfdSAndroid Build Coastguard Worker    help="trace only this pid")
50*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-t", "--tid", type=int,
51*387f9dfdSAndroid Build Coastguard Worker    help="trace only this tid")
52*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-c", "--ppid", type=int,
53*387f9dfdSAndroid Build Coastguard Worker    help="trace only child of this pid")
54*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-i", "--interval", type=int,
55*387f9dfdSAndroid Build Coastguard Worker    help="print summary at this interval (seconds)")
56*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-d", "--duration", type=int,
57*387f9dfdSAndroid Build Coastguard Worker    help="total duration of trace, in seconds")
58*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-T", "--top", type=int, default=10,
59*387f9dfdSAndroid Build Coastguard Worker    help="print only the top syscalls by count or latency")
60*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-x", "--failures", action="store_true",
61*387f9dfdSAndroid Build Coastguard Worker    help="trace only failed syscalls (return < 0)")
62*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-e", "--errno", type=handle_errno,
63*387f9dfdSAndroid Build Coastguard Worker    help="trace only syscalls that return this error (numeric or EPERM, etc.)")
64*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-L", "--latency", action="store_true",
65*387f9dfdSAndroid Build Coastguard Worker    help="collect syscall latency")
66*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-m", "--milliseconds", action="store_true",
67*387f9dfdSAndroid Build Coastguard Worker    help="display latency in milliseconds (default: microseconds)")
68*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-P", "--process", action="store_true",
69*387f9dfdSAndroid Build Coastguard Worker    help="count by process and not by syscall")
70*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-l", "--list", action="store_true",
71*387f9dfdSAndroid Build Coastguard Worker    help="print list of recognized syscalls and exit")
72*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--syscall", type=str,
73*387f9dfdSAndroid Build Coastguard Worker    help="trace this syscall only (use option -l to get all recognized syscalls)")
74*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true",
75*387f9dfdSAndroid Build Coastguard Worker    help=argparse.SUPPRESS)
76*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
77*387f9dfdSAndroid Build Coastguard Workerif args.duration and not args.interval:
78*387f9dfdSAndroid Build Coastguard Worker    args.interval = args.duration
79*387f9dfdSAndroid Build Coastguard Workerif not args.interval:
80*387f9dfdSAndroid Build Coastguard Worker    args.interval = 99999999
81*387f9dfdSAndroid Build Coastguard Worker
82*387f9dfdSAndroid Build Coastguard Workersyscall_nr = -1
83*387f9dfdSAndroid Build Coastguard Workerif args.syscall is not None:
84*387f9dfdSAndroid Build Coastguard Worker    syscall = bytes(args.syscall, 'utf-8')
85*387f9dfdSAndroid Build Coastguard Worker    for key, value in syscalls.items():
86*387f9dfdSAndroid Build Coastguard Worker        if syscall == value:
87*387f9dfdSAndroid Build Coastguard Worker            syscall_nr = key
88*387f9dfdSAndroid Build Coastguard Worker            break
89*387f9dfdSAndroid Build Coastguard Worker    if syscall_nr == -1:
90*387f9dfdSAndroid Build Coastguard Worker        print("Error: syscall '%s' not found. Exiting." % args.syscall)
91*387f9dfdSAndroid Build Coastguard Worker        sys.exit(1)
92*387f9dfdSAndroid Build Coastguard Worker
93*387f9dfdSAndroid Build Coastguard Workerif args.list:
94*387f9dfdSAndroid Build Coastguard Worker    for grp in izip_longest(*(iter(sorted(syscalls.values())),) * 4):
95*387f9dfdSAndroid Build Coastguard Worker        print("   ".join(["%-22s" % s.decode() for s in grp if s is not None]))
96*387f9dfdSAndroid Build Coastguard Worker    sys.exit(0)
97*387f9dfdSAndroid Build Coastguard Worker
98*387f9dfdSAndroid Build Coastguard Workertext = """
99*387f9dfdSAndroid Build Coastguard Worker#include <linux/sched.h>
100*387f9dfdSAndroid Build Coastguard Worker
101*387f9dfdSAndroid Build Coastguard Worker#ifdef LATENCY
102*387f9dfdSAndroid Build Coastguard Workerstruct data_t {
103*387f9dfdSAndroid Build Coastguard Worker    u64 count;
104*387f9dfdSAndroid Build Coastguard Worker    u64 total_ns;
105*387f9dfdSAndroid Build Coastguard Worker};
106*387f9dfdSAndroid Build Coastguard Worker
107*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(start, u64, u64);
108*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(data, u32, struct data_t);
109*387f9dfdSAndroid Build Coastguard Worker#else
110*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(data, u32, u64);
111*387f9dfdSAndroid Build Coastguard Worker#endif
112*387f9dfdSAndroid Build Coastguard Worker
113*387f9dfdSAndroid Build Coastguard Worker#ifdef LATENCY
114*387f9dfdSAndroid Build Coastguard WorkerTRACEPOINT_PROBE(raw_syscalls, sys_enter) {
115*387f9dfdSAndroid Build Coastguard Worker    u64 pid_tgid = bpf_get_current_pid_tgid();
116*387f9dfdSAndroid Build Coastguard Worker    u32 pid = pid_tgid >> 32;
117*387f9dfdSAndroid Build Coastguard Worker    u32 tid = (u32)pid_tgid;
118*387f9dfdSAndroid Build Coastguard Worker
119*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_SYSCALL_NR
120*387f9dfdSAndroid Build Coastguard Worker    if (args->id != FILTER_SYSCALL_NR)
121*387f9dfdSAndroid Build Coastguard Worker        return 0;
122*387f9dfdSAndroid Build Coastguard Worker#endif
123*387f9dfdSAndroid Build Coastguard Worker
124*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_PID
125*387f9dfdSAndroid Build Coastguard Worker    if (pid != FILTER_PID)
126*387f9dfdSAndroid Build Coastguard Worker        return 0;
127*387f9dfdSAndroid Build Coastguard Worker#endif
128*387f9dfdSAndroid Build Coastguard Worker
129*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_TID
130*387f9dfdSAndroid Build Coastguard Worker    if (tid != FILTER_TID)
131*387f9dfdSAndroid Build Coastguard Worker        return 0;
132*387f9dfdSAndroid Build Coastguard Worker#endif
133*387f9dfdSAndroid Build Coastguard Worker
134*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_PPID
135*387f9dfdSAndroid Build Coastguard Worker    struct task_struct *task = (struct task_struct *)bpf_get_current_task();
136*387f9dfdSAndroid Build Coastguard Worker    u32 ppid = task->real_parent->tgid;
137*387f9dfdSAndroid Build Coastguard Worker    if (ppid != FILTER_PPID)
138*387f9dfdSAndroid Build Coastguard Worker        return 0;
139*387f9dfdSAndroid Build Coastguard Worker#endif
140*387f9dfdSAndroid Build Coastguard Worker
141*387f9dfdSAndroid Build Coastguard Worker    u64 t = bpf_ktime_get_ns();
142*387f9dfdSAndroid Build Coastguard Worker    start.update(&pid_tgid, &t);
143*387f9dfdSAndroid Build Coastguard Worker    return 0;
144*387f9dfdSAndroid Build Coastguard Worker}
145*387f9dfdSAndroid Build Coastguard Worker#endif
146*387f9dfdSAndroid Build Coastguard Worker
147*387f9dfdSAndroid Build Coastguard WorkerTRACEPOINT_PROBE(raw_syscalls, sys_exit) {
148*387f9dfdSAndroid Build Coastguard Worker    u64 pid_tgid = bpf_get_current_pid_tgid();
149*387f9dfdSAndroid Build Coastguard Worker    u32 pid = pid_tgid >> 32;
150*387f9dfdSAndroid Build Coastguard Worker    u32 tid = (u32)pid_tgid;
151*387f9dfdSAndroid Build Coastguard Worker
152*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_SYSCALL_NR
153*387f9dfdSAndroid Build Coastguard Worker    if (args->id != FILTER_SYSCALL_NR)
154*387f9dfdSAndroid Build Coastguard Worker        return 0;
155*387f9dfdSAndroid Build Coastguard Worker#endif
156*387f9dfdSAndroid Build Coastguard Worker
157*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_PID
158*387f9dfdSAndroid Build Coastguard Worker    if (pid != FILTER_PID)
159*387f9dfdSAndroid Build Coastguard Worker        return 0;
160*387f9dfdSAndroid Build Coastguard Worker#endif
161*387f9dfdSAndroid Build Coastguard Worker
162*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_TID
163*387f9dfdSAndroid Build Coastguard Worker    if (tid != FILTER_TID)
164*387f9dfdSAndroid Build Coastguard Worker        return 0;
165*387f9dfdSAndroid Build Coastguard Worker#endif
166*387f9dfdSAndroid Build Coastguard Worker
167*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_PPID
168*387f9dfdSAndroid Build Coastguard Worker    struct task_struct *task = (struct task_struct *)bpf_get_current_task();
169*387f9dfdSAndroid Build Coastguard Worker    u32 ppid = task->real_parent->tgid;
170*387f9dfdSAndroid Build Coastguard Worker    if (ppid != FILTER_PPID)
171*387f9dfdSAndroid Build Coastguard Worker        return 0;
172*387f9dfdSAndroid Build Coastguard Worker#endif
173*387f9dfdSAndroid Build Coastguard Worker
174*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_FAILED
175*387f9dfdSAndroid Build Coastguard Worker    if (args->ret >= 0)
176*387f9dfdSAndroid Build Coastguard Worker        return 0;
177*387f9dfdSAndroid Build Coastguard Worker#endif
178*387f9dfdSAndroid Build Coastguard Worker
179*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_ERRNO
180*387f9dfdSAndroid Build Coastguard Worker    if (args->ret != -FILTER_ERRNO)
181*387f9dfdSAndroid Build Coastguard Worker        return 0;
182*387f9dfdSAndroid Build Coastguard Worker#endif
183*387f9dfdSAndroid Build Coastguard Worker
184*387f9dfdSAndroid Build Coastguard Worker#ifdef BY_PROCESS
185*387f9dfdSAndroid Build Coastguard Worker    u32 key = pid_tgid >> 32;
186*387f9dfdSAndroid Build Coastguard Worker#else
187*387f9dfdSAndroid Build Coastguard Worker    u32 key = args->id;
188*387f9dfdSAndroid Build Coastguard Worker#endif
189*387f9dfdSAndroid Build Coastguard Worker
190*387f9dfdSAndroid Build Coastguard Worker#ifdef LATENCY
191*387f9dfdSAndroid Build Coastguard Worker    struct data_t *val, zero = {};
192*387f9dfdSAndroid Build Coastguard Worker    u64 *start_ns = start.lookup(&pid_tgid);
193*387f9dfdSAndroid Build Coastguard Worker    if (!start_ns)
194*387f9dfdSAndroid Build Coastguard Worker        return 0;
195*387f9dfdSAndroid Build Coastguard Worker
196*387f9dfdSAndroid Build Coastguard Worker    val = data.lookup_or_try_init(&key, &zero);
197*387f9dfdSAndroid Build Coastguard Worker    if (val) {
198*387f9dfdSAndroid Build Coastguard Worker        lock_xadd(&val->count, 1);
199*387f9dfdSAndroid Build Coastguard Worker        lock_xadd(&val->total_ns, bpf_ktime_get_ns() - *start_ns);
200*387f9dfdSAndroid Build Coastguard Worker    }
201*387f9dfdSAndroid Build Coastguard Worker#else
202*387f9dfdSAndroid Build Coastguard Worker    u64 *val, zero = 0;
203*387f9dfdSAndroid Build Coastguard Worker    val = data.lookup_or_try_init(&key, &zero);
204*387f9dfdSAndroid Build Coastguard Worker    if (val) {
205*387f9dfdSAndroid Build Coastguard Worker        lock_xadd(val, 1);
206*387f9dfdSAndroid Build Coastguard Worker    }
207*387f9dfdSAndroid Build Coastguard Worker#endif
208*387f9dfdSAndroid Build Coastguard Worker    return 0;
209*387f9dfdSAndroid Build Coastguard Worker}
210*387f9dfdSAndroid Build Coastguard Worker"""
211*387f9dfdSAndroid Build Coastguard Worker
212*387f9dfdSAndroid Build Coastguard Workerif args.pid:
213*387f9dfdSAndroid Build Coastguard Worker    text = ("#define FILTER_PID %d\n" % args.pid) + text
214*387f9dfdSAndroid Build Coastguard Workerelif args.tid:
215*387f9dfdSAndroid Build Coastguard Worker    text = ("#define FILTER_TID %d\n" % args.tid) + text
216*387f9dfdSAndroid Build Coastguard Workerelif args.ppid:
217*387f9dfdSAndroid Build Coastguard Worker    text = ("#define FILTER_PPID %d\n" % args.ppid) + text
218*387f9dfdSAndroid Build Coastguard Workerif args.failures:
219*387f9dfdSAndroid Build Coastguard Worker    text = "#define FILTER_FAILED\n" + text
220*387f9dfdSAndroid Build Coastguard Workerif args.errno:
221*387f9dfdSAndroid Build Coastguard Worker    text = "#define FILTER_ERRNO %d\n" % abs(args.errno) + text
222*387f9dfdSAndroid Build Coastguard Workerif args.latency:
223*387f9dfdSAndroid Build Coastguard Worker    text = "#define LATENCY\n" + text
224*387f9dfdSAndroid Build Coastguard Workerif args.process:
225*387f9dfdSAndroid Build Coastguard Worker    text = "#define BY_PROCESS\n" + text
226*387f9dfdSAndroid Build Coastguard Workerif args.syscall is not None:
227*387f9dfdSAndroid Build Coastguard Worker    text = ("#define FILTER_SYSCALL_NR %d\n" % syscall_nr) + text
228*387f9dfdSAndroid Build Coastguard Workerif args.ebpf:
229*387f9dfdSAndroid Build Coastguard Worker    print(text)
230*387f9dfdSAndroid Build Coastguard Worker    exit()
231*387f9dfdSAndroid Build Coastguard Worker
232*387f9dfdSAndroid Build Coastguard Workerbpf = BPF(text=text)
233*387f9dfdSAndroid Build Coastguard Worker
234*387f9dfdSAndroid Build Coastguard Workerdef print_stats():
235*387f9dfdSAndroid Build Coastguard Worker    if args.latency:
236*387f9dfdSAndroid Build Coastguard Worker        print_latency_stats()
237*387f9dfdSAndroid Build Coastguard Worker    else:
238*387f9dfdSAndroid Build Coastguard Worker        print_count_stats()
239*387f9dfdSAndroid Build Coastguard Worker
240*387f9dfdSAndroid Build Coastguard Workeragg_colname = "PID    COMM" if args.process else "SYSCALL"
241*387f9dfdSAndroid Build Coastguard Workertime_colname = "TIME (ms)" if args.milliseconds else "TIME (us)"
242*387f9dfdSAndroid Build Coastguard Worker
243*387f9dfdSAndroid Build Coastguard Workerdef comm_for_pid(pid):
244*387f9dfdSAndroid Build Coastguard Worker    try:
245*387f9dfdSAndroid Build Coastguard Worker        return open("/proc/%d/comm" % pid, "rb").read().strip()
246*387f9dfdSAndroid Build Coastguard Worker    except Exception:
247*387f9dfdSAndroid Build Coastguard Worker        return b"[unknown]"
248*387f9dfdSAndroid Build Coastguard Worker
249*387f9dfdSAndroid Build Coastguard Workerdef agg_colval(key):
250*387f9dfdSAndroid Build Coastguard Worker    if args.process:
251*387f9dfdSAndroid Build Coastguard Worker        return b"%-6d %-15s" % (key.value, comm_for_pid(key.value))
252*387f9dfdSAndroid Build Coastguard Worker    else:
253*387f9dfdSAndroid Build Coastguard Worker        return syscall_name(key.value)
254*387f9dfdSAndroid Build Coastguard Worker
255*387f9dfdSAndroid Build Coastguard Workerdef print_count_stats():
256*387f9dfdSAndroid Build Coastguard Worker    data = bpf["data"]
257*387f9dfdSAndroid Build Coastguard Worker    print("[%s]" % strftime("%H:%M:%S"))
258*387f9dfdSAndroid Build Coastguard Worker    print("%-22s %8s" % (agg_colname, "COUNT"))
259*387f9dfdSAndroid Build Coastguard Worker    for k, v in sorted(data.items(), key=lambda kv: -kv[1].value)[:args.top]:
260*387f9dfdSAndroid Build Coastguard Worker        if k.value == 0xFFFFFFFF:
261*387f9dfdSAndroid Build Coastguard Worker            continue    # happens occasionally, we don't need it
262*387f9dfdSAndroid Build Coastguard Worker        printb(b"%-22s %8d" % (agg_colval(k), v.value))
263*387f9dfdSAndroid Build Coastguard Worker    print("")
264*387f9dfdSAndroid Build Coastguard Worker    data.clear()
265*387f9dfdSAndroid Build Coastguard Worker
266*387f9dfdSAndroid Build Coastguard Workerdef print_latency_stats():
267*387f9dfdSAndroid Build Coastguard Worker    data = bpf["data"]
268*387f9dfdSAndroid Build Coastguard Worker    print("[%s]" % strftime("%H:%M:%S"))
269*387f9dfdSAndroid Build Coastguard Worker    print("%-22s %8s %16s" % (agg_colname, "COUNT", time_colname))
270*387f9dfdSAndroid Build Coastguard Worker    for k, v in sorted(data.items(),
271*387f9dfdSAndroid Build Coastguard Worker                       key=lambda kv: -kv[1].total_ns)[:args.top]:
272*387f9dfdSAndroid Build Coastguard Worker        if k.value == 0xFFFFFFFF:
273*387f9dfdSAndroid Build Coastguard Worker            continue    # happens occasionally, we don't need it
274*387f9dfdSAndroid Build Coastguard Worker        printb((b"%-22s %8d " + (b"%16.6f" if args.milliseconds else b"%16.3f")) %
275*387f9dfdSAndroid Build Coastguard Worker               (agg_colval(k), v.count,
276*387f9dfdSAndroid Build Coastguard Worker                v.total_ns / (1e6 if args.milliseconds else 1e3)))
277*387f9dfdSAndroid Build Coastguard Worker    print("")
278*387f9dfdSAndroid Build Coastguard Worker    data.clear()
279*387f9dfdSAndroid Build Coastguard Worker
280*387f9dfdSAndroid Build Coastguard Workerif args.syscall is not None:
281*387f9dfdSAndroid Build Coastguard Worker    print("Tracing %ssyscall '%s'... Ctrl+C to quit." %
282*387f9dfdSAndroid Build Coastguard Worker        ("failed " if args.failures else "", args.syscall))
283*387f9dfdSAndroid Build Coastguard Workerelse:
284*387f9dfdSAndroid Build Coastguard Worker    print("Tracing %ssyscalls, printing top %d... Ctrl+C to quit." %
285*387f9dfdSAndroid Build Coastguard Worker        ("failed " if args.failures else "", args.top))
286*387f9dfdSAndroid Build Coastguard Workerexiting = 0 if args.interval else 1
287*387f9dfdSAndroid Build Coastguard Workerseconds = 0
288*387f9dfdSAndroid Build Coastguard Workerwhile True:
289*387f9dfdSAndroid Build Coastguard Worker    try:
290*387f9dfdSAndroid Build Coastguard Worker        sleep(args.interval)
291*387f9dfdSAndroid Build Coastguard Worker        seconds += args.interval
292*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
293*387f9dfdSAndroid Build Coastguard Worker        exiting = 1
294*387f9dfdSAndroid Build Coastguard Worker        signal.signal(signal.SIGINT, signal_ignore)
295*387f9dfdSAndroid Build Coastguard Worker    if args.duration and seconds >= args.duration:
296*387f9dfdSAndroid Build Coastguard Worker        exiting = 1
297*387f9dfdSAndroid Build Coastguard Worker
298*387f9dfdSAndroid Build Coastguard Worker    print_stats()
299*387f9dfdSAndroid Build Coastguard Worker
300*387f9dfdSAndroid Build Coastguard Worker    if exiting:
301*387f9dfdSAndroid Build Coastguard Worker        print("Detaching...")
302*387f9dfdSAndroid Build Coastguard Worker        exit()
303