1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/python 2*387f9dfdSAndroid Build Coastguard Worker# 3*387f9dfdSAndroid Build Coastguard Worker# offwaketime Summarize blocked time by kernel off-CPU stack + waker stack 4*387f9dfdSAndroid Build Coastguard Worker# For Linux, uses BCC, eBPF. 5*387f9dfdSAndroid Build Coastguard Worker# 6*387f9dfdSAndroid Build Coastguard Worker# USAGE: offwaketime [-h] [-u] [-p PID] [-T] [duration] 7*387f9dfdSAndroid Build Coastguard Worker# 8*387f9dfdSAndroid Build Coastguard Worker# The current implementation uses an unrolled loop for x86_64, and was written 9*387f9dfdSAndroid Build Coastguard Worker# as a proof of concept. This implementation should be replaced in the future 10*387f9dfdSAndroid Build Coastguard Worker# with an appropriate bpf_ call, when available. 11*387f9dfdSAndroid Build Coastguard Worker# 12*387f9dfdSAndroid Build Coastguard Worker# The Off-CPU stack is currently limited to a stack trace depth of 20 13*387f9dfdSAndroid Build Coastguard Worker# (maxtdepth), and the waker stack limited to 10 (maxwdepth). This is also 14*387f9dfdSAndroid Build Coastguard Worker# limited to kernel stacks, and x86_64 only. Check for future versions, where 15*387f9dfdSAndroid Build Coastguard Worker# these limitations should be removed. 16*387f9dfdSAndroid Build Coastguard Worker# 17*387f9dfdSAndroid Build Coastguard Worker# Copyright 2016 Netflix, Inc. 18*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License") 19*387f9dfdSAndroid Build Coastguard Worker# 20*387f9dfdSAndroid Build Coastguard Worker# 20-Jan-2016 Brendan Gregg Created this. 21*387f9dfdSAndroid Build Coastguard Worker 22*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function 23*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF 24*387f9dfdSAndroid Build Coastguard Workerfrom time import sleep 25*387f9dfdSAndroid Build Coastguard Workerimport argparse 26*387f9dfdSAndroid Build Coastguard Workerimport signal 27*387f9dfdSAndroid Build Coastguard Worker 28*387f9dfdSAndroid Build Coastguard Worker# arguments 29*387f9dfdSAndroid Build Coastguard Workerexamples = """examples: 30*387f9dfdSAndroid Build Coastguard Worker ./offwaketime # trace off-CPU + waker stack time until Ctrl-C 31*387f9dfdSAndroid Build Coastguard Worker ./offwaketime 5 # trace for 5 seconds only 32*387f9dfdSAndroid Build Coastguard Worker ./offwaketime -f 5 # 5 seconds, and output in folded format 33*387f9dfdSAndroid Build Coastguard Worker ./offwaketime -u # don't include kernel threads (user only) 34*387f9dfdSAndroid Build Coastguard Worker ./offwaketime -p 185 # trace fo PID 185 only 35*387f9dfdSAndroid Build Coastguard Worker""" 36*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser( 37*387f9dfdSAndroid Build Coastguard Worker description="Summarize blocked time by kernel stack trace + waker stack", 38*387f9dfdSAndroid Build Coastguard Worker formatter_class=argparse.RawDescriptionHelpFormatter, 39*387f9dfdSAndroid Build Coastguard Worker epilog=examples) 40*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-u", "--useronly", action="store_true", 41*387f9dfdSAndroid Build Coastguard Worker help="user threads only (no kernel threads)") 42*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid", 43*387f9dfdSAndroid Build Coastguard Worker help="trace this PID only") 44*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-v", "--verbose", action="store_true", 45*387f9dfdSAndroid Build Coastguard Worker help="show raw addresses") 46*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-f", "--folded", action="store_true", 47*387f9dfdSAndroid Build Coastguard Worker help="output folded format") 48*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("duration", nargs="?", default=99999999, 49*387f9dfdSAndroid Build Coastguard Worker help="duration of trace, in seconds") 50*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args() 51*387f9dfdSAndroid Build Coastguard Workerfolded = args.folded 52*387f9dfdSAndroid Build Coastguard Workerduration = int(args.duration) 53*387f9dfdSAndroid Build Coastguard Workerdebug = 0 54*387f9dfdSAndroid Build Coastguard Workermaxwdepth = 10 # and MAXWDEPTH 55*387f9dfdSAndroid Build Coastguard Workermaxtdepth = 20 # and MAXTDEPTH 56*387f9dfdSAndroid Build Coastguard Workerif args.pid and args.useronly: 57*387f9dfdSAndroid Build Coastguard Worker print("ERROR: use either -p or -u.") 58*387f9dfdSAndroid Build Coastguard Worker exit() 59*387f9dfdSAndroid Build Coastguard Worker 60*387f9dfdSAndroid Build Coastguard Worker# signal handler 61*387f9dfdSAndroid Build Coastguard Workerdef signal_ignore(signal, frame): 62*387f9dfdSAndroid Build Coastguard Worker print() 63*387f9dfdSAndroid Build Coastguard Worker 64*387f9dfdSAndroid Build Coastguard Worker# define BPF program 65*387f9dfdSAndroid Build Coastguard Workerbpf_text = """ 66*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h> 67*387f9dfdSAndroid Build Coastguard Worker#include <linux/sched.h> 68*387f9dfdSAndroid Build Coastguard Worker 69*387f9dfdSAndroid Build Coastguard Worker#define MAXWDEPTH 10 70*387f9dfdSAndroid Build Coastguard Worker#define MAXTDEPTH 20 71*387f9dfdSAndroid Build Coastguard Worker#define MINBLOCK_US 1 72*387f9dfdSAndroid Build Coastguard Worker 73*387f9dfdSAndroid Build Coastguard Workerstruct key_t { 74*387f9dfdSAndroid Build Coastguard Worker char waker[TASK_COMM_LEN]; 75*387f9dfdSAndroid Build Coastguard Worker char target[TASK_COMM_LEN]; 76*387f9dfdSAndroid Build Coastguard Worker u64 wret[MAXWDEPTH]; 77*387f9dfdSAndroid Build Coastguard Worker u64 tret[MAXTDEPTH]; 78*387f9dfdSAndroid Build Coastguard Worker}; 79*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(counts, struct key_t); 80*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(start, u32); 81*387f9dfdSAndroid Build Coastguard Workerstruct wokeby_t { 82*387f9dfdSAndroid Build Coastguard Worker char name[TASK_COMM_LEN]; 83*387f9dfdSAndroid Build Coastguard Worker u64 ret[MAXWDEPTH]; 84*387f9dfdSAndroid Build Coastguard Worker}; 85*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(wokeby, u32, struct wokeby_t); 86*387f9dfdSAndroid Build Coastguard Worker 87*387f9dfdSAndroid Build Coastguard Workerstatic u64 get_frame(u64 *bp) { 88*387f9dfdSAndroid Build Coastguard Worker if (*bp) { 89*387f9dfdSAndroid Build Coastguard Worker // The following stack walker is x86_64 specific 90*387f9dfdSAndroid Build Coastguard Worker u64 ret = 0; 91*387f9dfdSAndroid Build Coastguard Worker if (bpf_probe_read(&ret, sizeof(ret), (void *)(*bp+8))) 92*387f9dfdSAndroid Build Coastguard Worker return 0; 93*387f9dfdSAndroid Build Coastguard Worker if (bpf_probe_read(bp, sizeof(*bp), (void *)*bp)) 94*387f9dfdSAndroid Build Coastguard Worker *bp = 0; 95*387f9dfdSAndroid Build Coastguard Worker if (ret < __START_KERNEL_map) 96*387f9dfdSAndroid Build Coastguard Worker return 0; 97*387f9dfdSAndroid Build Coastguard Worker return ret; 98*387f9dfdSAndroid Build Coastguard Worker } 99*387f9dfdSAndroid Build Coastguard Worker return 0; 100*387f9dfdSAndroid Build Coastguard Worker} 101*387f9dfdSAndroid Build Coastguard Worker 102*387f9dfdSAndroid Build Coastguard Workerint waker(struct pt_regs *ctx, struct task_struct *p) { 103*387f9dfdSAndroid Build Coastguard Worker u32 pid = p->pid; 104*387f9dfdSAndroid Build Coastguard Worker 105*387f9dfdSAndroid Build Coastguard Worker if (!(FILTER)) 106*387f9dfdSAndroid Build Coastguard Worker return 0; 107*387f9dfdSAndroid Build Coastguard Worker 108*387f9dfdSAndroid Build Coastguard Worker u64 bp = 0; 109*387f9dfdSAndroid Build Coastguard Worker struct wokeby_t woke = {}; 110*387f9dfdSAndroid Build Coastguard Worker int depth = 0; 111*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&woke.name, sizeof(woke.name)); 112*387f9dfdSAndroid Build Coastguard Worker bp = ctx->bp; 113*387f9dfdSAndroid Build Coastguard Worker 114*387f9dfdSAndroid Build Coastguard Worker // unrolled loop (MAXWDEPTH): 115*387f9dfdSAndroid Build Coastguard Worker if (!(woke.ret[depth++] = get_frame(&bp))) goto out; 116*387f9dfdSAndroid Build Coastguard Worker if (!(woke.ret[depth++] = get_frame(&bp))) goto out; 117*387f9dfdSAndroid Build Coastguard Worker if (!(woke.ret[depth++] = get_frame(&bp))) goto out; 118*387f9dfdSAndroid Build Coastguard Worker if (!(woke.ret[depth++] = get_frame(&bp))) goto out; 119*387f9dfdSAndroid Build Coastguard Worker if (!(woke.ret[depth++] = get_frame(&bp))) goto out; 120*387f9dfdSAndroid Build Coastguard Worker if (!(woke.ret[depth++] = get_frame(&bp))) goto out; 121*387f9dfdSAndroid Build Coastguard Worker if (!(woke.ret[depth++] = get_frame(&bp))) goto out; 122*387f9dfdSAndroid Build Coastguard Worker if (!(woke.ret[depth++] = get_frame(&bp))) goto out; 123*387f9dfdSAndroid Build Coastguard Worker if (!(woke.ret[depth++] = get_frame(&bp))) goto out; 124*387f9dfdSAndroid Build Coastguard Worker woke.ret[depth] = get_frame(&bp); 125*387f9dfdSAndroid Build Coastguard Worker 126*387f9dfdSAndroid Build Coastguard Workerout: 127*387f9dfdSAndroid Build Coastguard Worker wokeby.update(&pid, &woke); 128*387f9dfdSAndroid Build Coastguard Worker return 0; 129*387f9dfdSAndroid Build Coastguard Worker} 130*387f9dfdSAndroid Build Coastguard Worker 131*387f9dfdSAndroid Build Coastguard Workerint oncpu(struct pt_regs *ctx, struct task_struct *p) { 132*387f9dfdSAndroid Build Coastguard Worker u32 pid = p->pid; 133*387f9dfdSAndroid Build Coastguard Worker u64 ts, *tsp; 134*387f9dfdSAndroid Build Coastguard Worker 135*387f9dfdSAndroid Build Coastguard Worker // record previous thread sleep time 136*387f9dfdSAndroid Build Coastguard Worker if (FILTER) { 137*387f9dfdSAndroid Build Coastguard Worker ts = bpf_ktime_get_ns(); 138*387f9dfdSAndroid Build Coastguard Worker start.update(&pid, &ts); 139*387f9dfdSAndroid Build Coastguard Worker } 140*387f9dfdSAndroid Build Coastguard Worker 141*387f9dfdSAndroid Build Coastguard Worker // calculate current thread's delta time 142*387f9dfdSAndroid Build Coastguard Worker pid = bpf_get_current_pid_tgid(); 143*387f9dfdSAndroid Build Coastguard Worker tsp = start.lookup(&pid); 144*387f9dfdSAndroid Build Coastguard Worker if (tsp == 0) 145*387f9dfdSAndroid Build Coastguard Worker return 0; // missed start or filtered 146*387f9dfdSAndroid Build Coastguard Worker u64 delta = bpf_ktime_get_ns() - *tsp; 147*387f9dfdSAndroid Build Coastguard Worker start.delete(&pid); 148*387f9dfdSAndroid Build Coastguard Worker delta = delta / 1000; 149*387f9dfdSAndroid Build Coastguard Worker if (delta < MINBLOCK_US) 150*387f9dfdSAndroid Build Coastguard Worker return 0; 151*387f9dfdSAndroid Build Coastguard Worker 152*387f9dfdSAndroid Build Coastguard Worker // create map key 153*387f9dfdSAndroid Build Coastguard Worker u64 zero = 0, *val, bp = 0; 154*387f9dfdSAndroid Build Coastguard Worker int depth = 0; 155*387f9dfdSAndroid Build Coastguard Worker struct key_t key = {}; 156*387f9dfdSAndroid Build Coastguard Worker struct wokeby_t *woke; 157*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&key.target, sizeof(key.target)); 158*387f9dfdSAndroid Build Coastguard Worker bp = ctx->bp; 159*387f9dfdSAndroid Build Coastguard Worker 160*387f9dfdSAndroid Build Coastguard Worker // unrolled loop (MAXTDEPTH): 161*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 162*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 163*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 164*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 165*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 166*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 167*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 168*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 169*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 170*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 171*387f9dfdSAndroid Build Coastguard Worker 172*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 173*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 174*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 175*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 176*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 177*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 178*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 179*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 180*387f9dfdSAndroid Build Coastguard Worker if (!(key.tret[depth++] = get_frame(&bp))) goto out; 181*387f9dfdSAndroid Build Coastguard Worker key.tret[depth] = get_frame(&bp); 182*387f9dfdSAndroid Build Coastguard Worker 183*387f9dfdSAndroid Build Coastguard Workerout: 184*387f9dfdSAndroid Build Coastguard Worker woke = wokeby.lookup(&pid); 185*387f9dfdSAndroid Build Coastguard Worker if (woke) { 186*387f9dfdSAndroid Build Coastguard Worker __builtin_memcpy(&key.wret, woke->ret, sizeof(key.wret)); 187*387f9dfdSAndroid Build Coastguard Worker __builtin_memcpy(&key.waker, woke->name, TASK_COMM_LEN); 188*387f9dfdSAndroid Build Coastguard Worker wokeby.delete(&pid); 189*387f9dfdSAndroid Build Coastguard Worker } 190*387f9dfdSAndroid Build Coastguard Worker 191*387f9dfdSAndroid Build Coastguard Worker val = counts.lookup_or_init(&key, &zero); 192*387f9dfdSAndroid Build Coastguard Worker if (val) { 193*387f9dfdSAndroid Build Coastguard Worker (*val) += delta; 194*387f9dfdSAndroid Build Coastguard Worker } 195*387f9dfdSAndroid Build Coastguard Worker return 0; 196*387f9dfdSAndroid Build Coastguard Worker} 197*387f9dfdSAndroid Build Coastguard Worker""" 198*387f9dfdSAndroid Build Coastguard Workerif args.pid: 199*387f9dfdSAndroid Build Coastguard Worker filter = 'pid == %s' % args.pid 200*387f9dfdSAndroid Build Coastguard Workerelif args.useronly: 201*387f9dfdSAndroid Build Coastguard Worker filter = '!(p->flags & PF_KTHREAD)' 202*387f9dfdSAndroid Build Coastguard Workerelse: 203*387f9dfdSAndroid Build Coastguard Worker filter = '1' 204*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace('FILTER', filter) 205*387f9dfdSAndroid Build Coastguard Workerif debug: 206*387f9dfdSAndroid Build Coastguard Worker print(bpf_text) 207*387f9dfdSAndroid Build Coastguard Worker 208*387f9dfdSAndroid Build Coastguard Worker# initialize BPF 209*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text) 210*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="finish_task_switch", fn_name="oncpu") 211*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="try_to_wake_up", fn_name="waker") 212*387f9dfdSAndroid Build Coastguard Workermatched = b.num_open_kprobes() 213*387f9dfdSAndroid Build Coastguard Workerif matched == 0: 214*387f9dfdSAndroid Build Coastguard Worker print("0 functions traced. Exiting.") 215*387f9dfdSAndroid Build Coastguard Worker exit() 216*387f9dfdSAndroid Build Coastguard Worker 217*387f9dfdSAndroid Build Coastguard Worker# header 218*387f9dfdSAndroid Build Coastguard Workerif not folded: 219*387f9dfdSAndroid Build Coastguard Worker print("Tracing blocked time (us) by kernel off-CPU and waker stack", 220*387f9dfdSAndroid Build Coastguard Worker end="") 221*387f9dfdSAndroid Build Coastguard Worker if duration < 99999999: 222*387f9dfdSAndroid Build Coastguard Worker print(" for %d secs." % duration) 223*387f9dfdSAndroid Build Coastguard Worker else: 224*387f9dfdSAndroid Build Coastguard Worker print("... Hit Ctrl-C to end.") 225*387f9dfdSAndroid Build Coastguard Worker 226*387f9dfdSAndroid Build Coastguard Worker# output 227*387f9dfdSAndroid Build Coastguard Workerwhile (1): 228*387f9dfdSAndroid Build Coastguard Worker try: 229*387f9dfdSAndroid Build Coastguard Worker sleep(duration) 230*387f9dfdSAndroid Build Coastguard Worker except KeyboardInterrupt: 231*387f9dfdSAndroid Build Coastguard Worker # as cleanup can take many seconds, trap Ctrl-C: 232*387f9dfdSAndroid Build Coastguard Worker signal.signal(signal.SIGINT, signal_ignore) 233*387f9dfdSAndroid Build Coastguard Worker 234*387f9dfdSAndroid Build Coastguard Worker if not folded: 235*387f9dfdSAndroid Build Coastguard Worker print() 236*387f9dfdSAndroid Build Coastguard Worker counts = b.get_table("counts") 237*387f9dfdSAndroid Build Coastguard Worker for k, v in sorted(counts.items(), key=lambda counts: counts[1].value): 238*387f9dfdSAndroid Build Coastguard Worker if folded: 239*387f9dfdSAndroid Build Coastguard Worker # fold target stack 240*387f9dfdSAndroid Build Coastguard Worker line = k.target + ";" 241*387f9dfdSAndroid Build Coastguard Worker for i in reversed(range(0, maxtdepth)): 242*387f9dfdSAndroid Build Coastguard Worker if k.tret[i] == 0: 243*387f9dfdSAndroid Build Coastguard Worker continue 244*387f9dfdSAndroid Build Coastguard Worker line = line + b.ksym(k.tret[i]) 245*387f9dfdSAndroid Build Coastguard Worker if i != 0: 246*387f9dfdSAndroid Build Coastguard Worker line = line + ";" 247*387f9dfdSAndroid Build Coastguard Worker 248*387f9dfdSAndroid Build Coastguard Worker # add delimiter 249*387f9dfdSAndroid Build Coastguard Worker line = line + ";-" 250*387f9dfdSAndroid Build Coastguard Worker 251*387f9dfdSAndroid Build Coastguard Worker # fold waker stack 252*387f9dfdSAndroid Build Coastguard Worker for i in range(0, maxwdepth): 253*387f9dfdSAndroid Build Coastguard Worker line = line + ";" 254*387f9dfdSAndroid Build Coastguard Worker if k.wret[i] == 0: 255*387f9dfdSAndroid Build Coastguard Worker break 256*387f9dfdSAndroid Build Coastguard Worker line = line + b.ksym(k.wret[i]) 257*387f9dfdSAndroid Build Coastguard Worker if i != 0: 258*387f9dfdSAndroid Build Coastguard Worker line = line + ";" + k.waker 259*387f9dfdSAndroid Build Coastguard Worker 260*387f9dfdSAndroid Build Coastguard Worker # print as a line 261*387f9dfdSAndroid Build Coastguard Worker print("%s %d" % (line, v.value)) 262*387f9dfdSAndroid Build Coastguard Worker else: 263*387f9dfdSAndroid Build Coastguard Worker # print wakeup name then stack in reverse order 264*387f9dfdSAndroid Build Coastguard Worker print(" %-16s %s" % ("waker:", k.waker)) 265*387f9dfdSAndroid Build Coastguard Worker for i in reversed(range(0, maxwdepth)): 266*387f9dfdSAndroid Build Coastguard Worker if k.wret[i] == 0: 267*387f9dfdSAndroid Build Coastguard Worker continue 268*387f9dfdSAndroid Build Coastguard Worker print(" %-16x %s" % (k.wret[i], 269*387f9dfdSAndroid Build Coastguard Worker b.ksym(k.wret[i]))) 270*387f9dfdSAndroid Build Coastguard Worker 271*387f9dfdSAndroid Build Coastguard Worker # print delimiter 272*387f9dfdSAndroid Build Coastguard Worker print(" %-16s %s" % ("-", "-")) 273*387f9dfdSAndroid Build Coastguard Worker 274*387f9dfdSAndroid Build Coastguard Worker # print default multi-line stack output 275*387f9dfdSAndroid Build Coastguard Worker for i in range(0, maxtdepth): 276*387f9dfdSAndroid Build Coastguard Worker if k.tret[i] == 0: 277*387f9dfdSAndroid Build Coastguard Worker break 278*387f9dfdSAndroid Build Coastguard Worker print(" %-16x %s" % (k.tret[i], 279*387f9dfdSAndroid Build Coastguard Worker b.ksym(k.tret[i]))) 280*387f9dfdSAndroid Build Coastguard Worker print(" %-16s %s" % ("target:", k.target)) 281*387f9dfdSAndroid Build Coastguard Worker print(" %d\n" % v.value) 282*387f9dfdSAndroid Build Coastguard Worker counts.clear() 283*387f9dfdSAndroid Build Coastguard Worker 284*387f9dfdSAndroid Build Coastguard Worker if not folded: 285*387f9dfdSAndroid Build Coastguard Worker print("Detaching...") 286*387f9dfdSAndroid Build Coastguard Worker exit() 287