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