1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python 2*387f9dfdSAndroid Build Coastguard Worker# @lint-avoid-python-3-compatibility-imports 3*387f9dfdSAndroid Build Coastguard Worker# 4*387f9dfdSAndroid Build Coastguard Worker# execsnoop Trace new processes via exec() syscalls. 5*387f9dfdSAndroid Build Coastguard Worker# For Linux, uses BCC, eBPF. Embedded C. 6*387f9dfdSAndroid Build Coastguard Worker# 7*387f9dfdSAndroid Build Coastguard Worker# USAGE: execsnoop [-h] [-T] [-t] [-x] [--cgroupmap CGROUPMAP] 8*387f9dfdSAndroid Build Coastguard Worker# [--mntnsmap MNTNSMAP] [-u USER] [-q] [-n NAME] [-l LINE] 9*387f9dfdSAndroid Build Coastguard Worker# [-U] [--max-args MAX_ARGS] [-P PPID] 10*387f9dfdSAndroid Build Coastguard Worker# 11*387f9dfdSAndroid Build Coastguard Worker# This currently will print up to a maximum of 19 arguments, plus the process 12*387f9dfdSAndroid Build Coastguard Worker# name, so 20 fields in total (MAXARG). 13*387f9dfdSAndroid Build Coastguard Worker# 14*387f9dfdSAndroid Build Coastguard Worker# This won't catch all new processes: an application may fork() but not exec(). 15*387f9dfdSAndroid Build Coastguard Worker# 16*387f9dfdSAndroid Build Coastguard Worker# Copyright 2016 Netflix, Inc. 17*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License") 18*387f9dfdSAndroid Build Coastguard Worker# 19*387f9dfdSAndroid Build Coastguard Worker# 07-Feb-2016 Brendan Gregg Created this. 20*387f9dfdSAndroid Build Coastguard Worker# 11-Aug-2022 Rocky Xing Added PPID filter support. 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 bcc.containers import filter_by_containers 25*387f9dfdSAndroid Build Coastguard Workerfrom bcc.utils import ArgString, printb 26*387f9dfdSAndroid Build Coastguard Workerimport bcc.utils as utils 27*387f9dfdSAndroid Build Coastguard Workerimport argparse 28*387f9dfdSAndroid Build Coastguard Workerimport re 29*387f9dfdSAndroid Build Coastguard Workerimport time 30*387f9dfdSAndroid Build Coastguard Workerimport pwd 31*387f9dfdSAndroid Build Coastguard Workerfrom collections import defaultdict 32*387f9dfdSAndroid Build Coastguard Workerfrom time import strftime 33*387f9dfdSAndroid Build Coastguard Worker 34*387f9dfdSAndroid Build Coastguard Worker 35*387f9dfdSAndroid Build Coastguard Workerdef parse_uid(user): 36*387f9dfdSAndroid Build Coastguard Worker try: 37*387f9dfdSAndroid Build Coastguard Worker result = int(user) 38*387f9dfdSAndroid Build Coastguard Worker except ValueError: 39*387f9dfdSAndroid Build Coastguard Worker try: 40*387f9dfdSAndroid Build Coastguard Worker user_info = pwd.getpwnam(user) 41*387f9dfdSAndroid Build Coastguard Worker except KeyError: 42*387f9dfdSAndroid Build Coastguard Worker raise argparse.ArgumentTypeError( 43*387f9dfdSAndroid Build Coastguard Worker "{0!r} is not valid UID or user entry".format(user)) 44*387f9dfdSAndroid Build Coastguard Worker else: 45*387f9dfdSAndroid Build Coastguard Worker return user_info.pw_uid 46*387f9dfdSAndroid Build Coastguard Worker else: 47*387f9dfdSAndroid Build Coastguard Worker # Maybe validate if UID < 0 ? 48*387f9dfdSAndroid Build Coastguard Worker return result 49*387f9dfdSAndroid Build Coastguard Worker 50*387f9dfdSAndroid Build Coastguard Worker 51*387f9dfdSAndroid Build Coastguard Worker# arguments 52*387f9dfdSAndroid Build Coastguard Workerexamples = """examples: 53*387f9dfdSAndroid Build Coastguard Worker ./execsnoop # trace all exec() syscalls 54*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -x # include failed exec()s 55*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -T # include time (HH:MM:SS) 56*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -P 181 # only trace new processes whose parent PID is 181 57*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -U # include UID 58*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -u 1000 # only trace UID 1000 59*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -u user # get user UID and trace only them 60*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -t # include timestamps 61*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -q # add "quotemarks" around arguments 62*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -n main # only print command lines containing "main" 63*387f9dfdSAndroid Build Coastguard Worker ./execsnoop -l tpkg # only print command where arguments contains "tpkg" 64*387f9dfdSAndroid Build Coastguard Worker ./execsnoop --cgroupmap mappath # only trace cgroups in this BPF map 65*387f9dfdSAndroid Build Coastguard Worker ./execsnoop --mntnsmap mappath # only trace mount namespaces in the map 66*387f9dfdSAndroid Build Coastguard Worker""" 67*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser( 68*387f9dfdSAndroid Build Coastguard Worker description="Trace exec() syscalls", 69*387f9dfdSAndroid Build Coastguard Worker formatter_class=argparse.RawDescriptionHelpFormatter, 70*387f9dfdSAndroid Build Coastguard Worker epilog=examples) 71*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-T", "--time", action="store_true", 72*387f9dfdSAndroid Build Coastguard Worker help="include time column on output (HH:MM:SS)") 73*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-t", "--timestamp", action="store_true", 74*387f9dfdSAndroid Build Coastguard Worker help="include timestamp on output") 75*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-x", "--fails", action="store_true", 76*387f9dfdSAndroid Build Coastguard Worker help="include failed exec()s") 77*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--cgroupmap", 78*387f9dfdSAndroid Build Coastguard Worker help="trace cgroups in this BPF map only") 79*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--mntnsmap", 80*387f9dfdSAndroid Build Coastguard Worker help="trace mount namespaces in this BPF map only") 81*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-u", "--uid", type=parse_uid, metavar='USER', 82*387f9dfdSAndroid Build Coastguard Worker help="trace this UID only") 83*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-q", "--quote", action="store_true", 84*387f9dfdSAndroid Build Coastguard Worker help="Add quotemarks (\") around arguments." 85*387f9dfdSAndroid Build Coastguard Worker ) 86*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-n", "--name", 87*387f9dfdSAndroid Build Coastguard Worker type=ArgString, 88*387f9dfdSAndroid Build Coastguard Worker help="only print commands matching this name (regex), any arg") 89*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-l", "--line", 90*387f9dfdSAndroid Build Coastguard Worker type=ArgString, 91*387f9dfdSAndroid Build Coastguard Worker help="only print commands where arg contains this line (regex)") 92*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-U", "--print-uid", action="store_true", 93*387f9dfdSAndroid Build Coastguard Worker help="print UID column") 94*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--max-args", default="20", 95*387f9dfdSAndroid Build Coastguard Worker help="maximum number of arguments parsed and displayed, defaults to 20") 96*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-P", "--ppid", 97*387f9dfdSAndroid Build Coastguard Worker help="trace this parent PID only") 98*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true", 99*387f9dfdSAndroid Build Coastguard Worker help=argparse.SUPPRESS) 100*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args() 101*387f9dfdSAndroid Build Coastguard Worker 102*387f9dfdSAndroid Build Coastguard Worker# define BPF program 103*387f9dfdSAndroid Build Coastguard Workerbpf_text = """ 104*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h> 105*387f9dfdSAndroid Build Coastguard Worker#include <linux/sched.h> 106*387f9dfdSAndroid Build Coastguard Worker#include <linux/fs.h> 107*387f9dfdSAndroid Build Coastguard Worker 108*387f9dfdSAndroid Build Coastguard Worker#define ARGSIZE 128 109*387f9dfdSAndroid Build Coastguard Worker 110*387f9dfdSAndroid Build Coastguard Workerenum event_type { 111*387f9dfdSAndroid Build Coastguard Worker EVENT_ARG, 112*387f9dfdSAndroid Build Coastguard Worker EVENT_RET, 113*387f9dfdSAndroid Build Coastguard Worker}; 114*387f9dfdSAndroid Build Coastguard Worker 115*387f9dfdSAndroid Build Coastguard Workerstruct data_t { 116*387f9dfdSAndroid Build Coastguard Worker u32 pid; // PID as in the userspace term (i.e. task->tgid in kernel) 117*387f9dfdSAndroid Build Coastguard Worker u32 ppid; // Parent PID as in the userspace term (i.e task->real_parent->tgid in kernel) 118*387f9dfdSAndroid Build Coastguard Worker u32 uid; 119*387f9dfdSAndroid Build Coastguard Worker char comm[TASK_COMM_LEN]; 120*387f9dfdSAndroid Build Coastguard Worker enum event_type type; 121*387f9dfdSAndroid Build Coastguard Worker char argv[ARGSIZE]; 122*387f9dfdSAndroid Build Coastguard Worker int retval; 123*387f9dfdSAndroid Build Coastguard Worker}; 124*387f9dfdSAndroid Build Coastguard Worker 125*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(events); 126*387f9dfdSAndroid Build Coastguard Worker 127*387f9dfdSAndroid Build Coastguard Workerstatic int __submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data) 128*387f9dfdSAndroid Build Coastguard Worker{ 129*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_user(data->argv, sizeof(data->argv), ptr); 130*387f9dfdSAndroid Build Coastguard Worker events.perf_submit(ctx, data, sizeof(struct data_t)); 131*387f9dfdSAndroid Build Coastguard Worker return 1; 132*387f9dfdSAndroid Build Coastguard Worker} 133*387f9dfdSAndroid Build Coastguard Worker 134*387f9dfdSAndroid Build Coastguard Workerstatic int submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data) 135*387f9dfdSAndroid Build Coastguard Worker{ 136*387f9dfdSAndroid Build Coastguard Worker const char *argp = NULL; 137*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_user(&argp, sizeof(argp), ptr); 138*387f9dfdSAndroid Build Coastguard Worker if (argp) { 139*387f9dfdSAndroid Build Coastguard Worker return __submit_arg(ctx, (void *)(argp), data); 140*387f9dfdSAndroid Build Coastguard Worker } 141*387f9dfdSAndroid Build Coastguard Worker return 0; 142*387f9dfdSAndroid Build Coastguard Worker} 143*387f9dfdSAndroid Build Coastguard Worker 144*387f9dfdSAndroid Build Coastguard Workerint syscall__execve(struct pt_regs *ctx, 145*387f9dfdSAndroid Build Coastguard Worker const char __user *filename, 146*387f9dfdSAndroid Build Coastguard Worker const char __user *const __user *__argv, 147*387f9dfdSAndroid Build Coastguard Worker const char __user *const __user *__envp) 148*387f9dfdSAndroid Build Coastguard Worker{ 149*387f9dfdSAndroid Build Coastguard Worker 150*387f9dfdSAndroid Build Coastguard Worker u32 uid = bpf_get_current_uid_gid() & 0xffffffff; 151*387f9dfdSAndroid Build Coastguard Worker 152*387f9dfdSAndroid Build Coastguard Worker UID_FILTER 153*387f9dfdSAndroid Build Coastguard Worker 154*387f9dfdSAndroid Build Coastguard Worker if (container_should_be_filtered()) { 155*387f9dfdSAndroid Build Coastguard Worker return 0; 156*387f9dfdSAndroid Build Coastguard Worker } 157*387f9dfdSAndroid Build Coastguard Worker 158*387f9dfdSAndroid Build Coastguard Worker // create data here and pass to submit_arg to save stack space (#555) 159*387f9dfdSAndroid Build Coastguard Worker struct data_t data = {}; 160*387f9dfdSAndroid Build Coastguard Worker struct task_struct *task; 161*387f9dfdSAndroid Build Coastguard Worker 162*387f9dfdSAndroid Build Coastguard Worker data.pid = bpf_get_current_pid_tgid() >> 32; 163*387f9dfdSAndroid Build Coastguard Worker 164*387f9dfdSAndroid Build Coastguard Worker task = (struct task_struct *)bpf_get_current_task(); 165*387f9dfdSAndroid Build Coastguard Worker // Some kernels, like Ubuntu 4.13.0-generic, return 0 166*387f9dfdSAndroid Build Coastguard Worker // as the real_parent->tgid. 167*387f9dfdSAndroid Build Coastguard Worker // We use the get_ppid function as a fallback in those cases. (#1883) 168*387f9dfdSAndroid Build Coastguard Worker data.ppid = task->real_parent->tgid; 169*387f9dfdSAndroid Build Coastguard Worker 170*387f9dfdSAndroid Build Coastguard Worker PPID_FILTER 171*387f9dfdSAndroid Build Coastguard Worker 172*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&data.comm, sizeof(data.comm)); 173*387f9dfdSAndroid Build Coastguard Worker data.type = EVENT_ARG; 174*387f9dfdSAndroid Build Coastguard Worker 175*387f9dfdSAndroid Build Coastguard Worker __submit_arg(ctx, (void *)filename, &data); 176*387f9dfdSAndroid Build Coastguard Worker 177*387f9dfdSAndroid Build Coastguard Worker // skip first arg, as we submitted filename 178*387f9dfdSAndroid Build Coastguard Worker #pragma unroll 179*387f9dfdSAndroid Build Coastguard Worker for (int i = 1; i < MAXARG; i++) { 180*387f9dfdSAndroid Build Coastguard Worker if (submit_arg(ctx, (void *)&__argv[i], &data) == 0) 181*387f9dfdSAndroid Build Coastguard Worker goto out; 182*387f9dfdSAndroid Build Coastguard Worker } 183*387f9dfdSAndroid Build Coastguard Worker 184*387f9dfdSAndroid Build Coastguard Worker // handle truncated argument list 185*387f9dfdSAndroid Build Coastguard Worker char ellipsis[] = "..."; 186*387f9dfdSAndroid Build Coastguard Worker __submit_arg(ctx, (void *)ellipsis, &data); 187*387f9dfdSAndroid Build Coastguard Workerout: 188*387f9dfdSAndroid Build Coastguard Worker return 0; 189*387f9dfdSAndroid Build Coastguard Worker} 190*387f9dfdSAndroid Build Coastguard Worker 191*387f9dfdSAndroid Build Coastguard Workerint do_ret_sys_execve(struct pt_regs *ctx) 192*387f9dfdSAndroid Build Coastguard Worker{ 193*387f9dfdSAndroid Build Coastguard Worker if (container_should_be_filtered()) { 194*387f9dfdSAndroid Build Coastguard Worker return 0; 195*387f9dfdSAndroid Build Coastguard Worker } 196*387f9dfdSAndroid Build Coastguard Worker 197*387f9dfdSAndroid Build Coastguard Worker struct data_t data = {}; 198*387f9dfdSAndroid Build Coastguard Worker struct task_struct *task; 199*387f9dfdSAndroid Build Coastguard Worker 200*387f9dfdSAndroid Build Coastguard Worker u32 uid = bpf_get_current_uid_gid() & 0xffffffff; 201*387f9dfdSAndroid Build Coastguard Worker UID_FILTER 202*387f9dfdSAndroid Build Coastguard Worker 203*387f9dfdSAndroid Build Coastguard Worker data.pid = bpf_get_current_pid_tgid() >> 32; 204*387f9dfdSAndroid Build Coastguard Worker data.uid = uid; 205*387f9dfdSAndroid Build Coastguard Worker 206*387f9dfdSAndroid Build Coastguard Worker task = (struct task_struct *)bpf_get_current_task(); 207*387f9dfdSAndroid Build Coastguard Worker // Some kernels, like Ubuntu 4.13.0-generic, return 0 208*387f9dfdSAndroid Build Coastguard Worker // as the real_parent->tgid. 209*387f9dfdSAndroid Build Coastguard Worker // We use the get_ppid function as a fallback in those cases. (#1883) 210*387f9dfdSAndroid Build Coastguard Worker data.ppid = task->real_parent->tgid; 211*387f9dfdSAndroid Build Coastguard Worker 212*387f9dfdSAndroid Build Coastguard Worker PPID_FILTER 213*387f9dfdSAndroid Build Coastguard Worker 214*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&data.comm, sizeof(data.comm)); 215*387f9dfdSAndroid Build Coastguard Worker data.type = EVENT_RET; 216*387f9dfdSAndroid Build Coastguard Worker data.retval = PT_REGS_RC(ctx); 217*387f9dfdSAndroid Build Coastguard Worker events.perf_submit(ctx, &data, sizeof(data)); 218*387f9dfdSAndroid Build Coastguard Worker 219*387f9dfdSAndroid Build Coastguard Worker return 0; 220*387f9dfdSAndroid Build Coastguard Worker} 221*387f9dfdSAndroid Build Coastguard Worker""" 222*387f9dfdSAndroid Build Coastguard Worker 223*387f9dfdSAndroid Build Coastguard Workerbpf_text = bpf_text.replace("MAXARG", args.max_args) 224*387f9dfdSAndroid Build Coastguard Worker 225*387f9dfdSAndroid Build Coastguard Workerif args.uid: 226*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('UID_FILTER', 227*387f9dfdSAndroid Build Coastguard Worker 'if (uid != %s) { return 0; }' % args.uid) 228*387f9dfdSAndroid Build Coastguard Workerelse: 229*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('UID_FILTER', '') 230*387f9dfdSAndroid Build Coastguard Worker 231*387f9dfdSAndroid Build Coastguard Workerif args.ppid: 232*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('PPID_FILTER', 233*387f9dfdSAndroid Build Coastguard Worker 'if (data.ppid != %s) { return 0; }' % args.ppid) 234*387f9dfdSAndroid Build Coastguard Workerelse: 235*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('PPID_FILTER', '') 236*387f9dfdSAndroid Build Coastguard Worker 237*387f9dfdSAndroid Build Coastguard Workerbpf_text = filter_by_containers(args) + bpf_text 238*387f9dfdSAndroid Build Coastguard Workerif args.ebpf: 239*387f9dfdSAndroid Build Coastguard Worker print(bpf_text) 240*387f9dfdSAndroid Build Coastguard Worker exit() 241*387f9dfdSAndroid Build Coastguard Worker 242*387f9dfdSAndroid Build Coastguard Worker# initialize BPF 243*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text) 244*387f9dfdSAndroid Build Coastguard Workerexecve_fnname = b.get_syscall_fnname("execve") 245*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event=execve_fnname, fn_name="syscall__execve") 246*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event=execve_fnname, fn_name="do_ret_sys_execve") 247*387f9dfdSAndroid Build Coastguard Worker 248*387f9dfdSAndroid Build Coastguard Worker# header 249*387f9dfdSAndroid Build Coastguard Workerif args.time: 250*387f9dfdSAndroid Build Coastguard Worker print("%-9s" % ("TIME"), end="") 251*387f9dfdSAndroid Build Coastguard Workerif args.timestamp: 252*387f9dfdSAndroid Build Coastguard Worker print("%-8s" % ("TIME(s)"), end="") 253*387f9dfdSAndroid Build Coastguard Workerif args.print_uid: 254*387f9dfdSAndroid Build Coastguard Worker print("%-6s" % ("UID"), end="") 255*387f9dfdSAndroid Build Coastguard Workerprint("%-16s %-7s %-7s %3s %s" % ("PCOMM", "PID", "PPID", "RET", "ARGS")) 256*387f9dfdSAndroid Build Coastguard Worker 257*387f9dfdSAndroid Build Coastguard Workerclass EventType(object): 258*387f9dfdSAndroid Build Coastguard Worker EVENT_ARG = 0 259*387f9dfdSAndroid Build Coastguard Worker EVENT_RET = 1 260*387f9dfdSAndroid Build Coastguard Worker 261*387f9dfdSAndroid Build Coastguard Workerstart_ts = time.time() 262*387f9dfdSAndroid Build Coastguard Workerargv = defaultdict(list) 263*387f9dfdSAndroid Build Coastguard Worker 264*387f9dfdSAndroid Build Coastguard Worker# This is best-effort PPID matching. Short-lived processes may exit 265*387f9dfdSAndroid Build Coastguard Worker# before we get a chance to read the PPID. 266*387f9dfdSAndroid Build Coastguard Worker# This is a fallback for when fetching the PPID from task->real_parent->tgip 267*387f9dfdSAndroid Build Coastguard Worker# returns 0, which happens in some kernel versions. 268*387f9dfdSAndroid Build Coastguard Workerdef get_ppid(pid): 269*387f9dfdSAndroid Build Coastguard Worker try: 270*387f9dfdSAndroid Build Coastguard Worker with open("/proc/%d/status" % pid) as status: 271*387f9dfdSAndroid Build Coastguard Worker for line in status: 272*387f9dfdSAndroid Build Coastguard Worker if line.startswith("PPid:"): 273*387f9dfdSAndroid Build Coastguard Worker return int(line.split()[1]) 274*387f9dfdSAndroid Build Coastguard Worker except IOError: 275*387f9dfdSAndroid Build Coastguard Worker pass 276*387f9dfdSAndroid Build Coastguard Worker return 0 277*387f9dfdSAndroid Build Coastguard Worker 278*387f9dfdSAndroid Build Coastguard Worker# process event 279*387f9dfdSAndroid Build Coastguard Workerdef print_event(cpu, data, size): 280*387f9dfdSAndroid Build Coastguard Worker event = b["events"].event(data) 281*387f9dfdSAndroid Build Coastguard Worker skip = False 282*387f9dfdSAndroid Build Coastguard Worker 283*387f9dfdSAndroid Build Coastguard Worker if event.type == EventType.EVENT_ARG: 284*387f9dfdSAndroid Build Coastguard Worker argv[event.pid].append(event.argv) 285*387f9dfdSAndroid Build Coastguard Worker elif event.type == EventType.EVENT_RET: 286*387f9dfdSAndroid Build Coastguard Worker if event.retval != 0 and not args.fails: 287*387f9dfdSAndroid Build Coastguard Worker skip = True 288*387f9dfdSAndroid Build Coastguard Worker if args.name and not re.search(bytes(args.name), event.comm): 289*387f9dfdSAndroid Build Coastguard Worker skip = True 290*387f9dfdSAndroid Build Coastguard Worker if args.line and not re.search(bytes(args.line), 291*387f9dfdSAndroid Build Coastguard Worker b' '.join(argv[event.pid])): 292*387f9dfdSAndroid Build Coastguard Worker skip = True 293*387f9dfdSAndroid Build Coastguard Worker if args.quote: 294*387f9dfdSAndroid Build Coastguard Worker argv[event.pid] = [ 295*387f9dfdSAndroid Build Coastguard Worker b"\"" + arg.replace(b"\"", b"\\\"") + b"\"" 296*387f9dfdSAndroid Build Coastguard Worker for arg in argv[event.pid] 297*387f9dfdSAndroid Build Coastguard Worker ] 298*387f9dfdSAndroid Build Coastguard Worker 299*387f9dfdSAndroid Build Coastguard Worker if not skip: 300*387f9dfdSAndroid Build Coastguard Worker if args.time: 301*387f9dfdSAndroid Build Coastguard Worker printb(b"%-9s" % strftime("%H:%M:%S").encode('ascii'), nl="") 302*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 303*387f9dfdSAndroid Build Coastguard Worker printb(b"%-8.3f" % (time.time() - start_ts), nl="") 304*387f9dfdSAndroid Build Coastguard Worker if args.print_uid: 305*387f9dfdSAndroid Build Coastguard Worker printb(b"%-6d" % event.uid, nl="") 306*387f9dfdSAndroid Build Coastguard Worker ppid = event.ppid if event.ppid > 0 else get_ppid(event.pid) 307*387f9dfdSAndroid Build Coastguard Worker ppid = b"%d" % ppid if ppid > 0 else b"?" 308*387f9dfdSAndroid Build Coastguard Worker argv_text = b' '.join(argv[event.pid]).replace(b'\n', b'\\n') 309*387f9dfdSAndroid Build Coastguard Worker printb(b"%-16s %-7d %-7s %3d %s" % (event.comm, event.pid, 310*387f9dfdSAndroid Build Coastguard Worker ppid, event.retval, argv_text)) 311*387f9dfdSAndroid Build Coastguard Worker try: 312*387f9dfdSAndroid Build Coastguard Worker del(argv[event.pid]) 313*387f9dfdSAndroid Build Coastguard Worker except Exception: 314*387f9dfdSAndroid Build Coastguard Worker pass 315*387f9dfdSAndroid Build Coastguard Worker 316*387f9dfdSAndroid Build Coastguard Worker 317*387f9dfdSAndroid Build Coastguard Worker# loop with callback to print_event 318*387f9dfdSAndroid Build Coastguard Workerb["events"].open_perf_buffer(print_event) 319*387f9dfdSAndroid Build Coastguard Workerwhile 1: 320*387f9dfdSAndroid Build Coastguard Worker try: 321*387f9dfdSAndroid Build Coastguard Worker b.perf_buffer_poll() 322*387f9dfdSAndroid Build Coastguard Worker except KeyboardInterrupt: 323*387f9dfdSAndroid Build Coastguard Worker exit() 324