1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/python 2*387f9dfdSAndroid Build Coastguard Worker# @lint-avoid-python-3-compatibility-imports 3*387f9dfdSAndroid Build Coastguard Worker# 4*387f9dfdSAndroid Build Coastguard Worker# opensnoop Trace open() syscalls. 5*387f9dfdSAndroid Build Coastguard Worker# For Linux, uses BCC, eBPF. Embedded C. 6*387f9dfdSAndroid Build Coastguard Worker# 7*387f9dfdSAndroid Build Coastguard Worker# USAGE: opensnoop [-h] [-t] [-x] [-p PID] 8*387f9dfdSAndroid Build Coastguard Worker# 9*387f9dfdSAndroid Build Coastguard Worker# Copyright (c) 2015 Brendan Gregg. 10*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License") 11*387f9dfdSAndroid Build Coastguard Worker# 12*387f9dfdSAndroid Build Coastguard Worker# 17-Sep-2015 Brendan Gregg Created this. 13*387f9dfdSAndroid Build Coastguard Worker 14*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function 15*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF 16*387f9dfdSAndroid Build Coastguard Workerimport argparse 17*387f9dfdSAndroid Build Coastguard Worker 18*387f9dfdSAndroid Build Coastguard Worker# arguments 19*387f9dfdSAndroid Build Coastguard Workerexamples = """examples: 20*387f9dfdSAndroid Build Coastguard Worker ./opensnoop # trace all open() syscalls 21*387f9dfdSAndroid Build Coastguard Worker ./opensnoop -t # include timestamps 22*387f9dfdSAndroid Build Coastguard Worker ./opensnoop -x # only show failed opens 23*387f9dfdSAndroid Build Coastguard Worker ./opensnoop -p 181 # only trace PID 181 24*387f9dfdSAndroid Build Coastguard Worker""" 25*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser( 26*387f9dfdSAndroid Build Coastguard Worker description="Trace open() syscalls", 27*387f9dfdSAndroid Build Coastguard Worker formatter_class=argparse.RawDescriptionHelpFormatter, 28*387f9dfdSAndroid Build Coastguard Worker epilog=examples) 29*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-t", "--timestamp", action="store_true", 30*387f9dfdSAndroid Build Coastguard Worker help="include timestamp on output") 31*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-x", "--failed", action="store_true", 32*387f9dfdSAndroid Build Coastguard Worker help="only show failed opens") 33*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid", 34*387f9dfdSAndroid Build Coastguard Worker help="trace this PID only") 35*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args() 36*387f9dfdSAndroid Build Coastguard Workerdebug = 0 37*387f9dfdSAndroid Build Coastguard Worker 38*387f9dfdSAndroid Build Coastguard Worker# define BPF program 39*387f9dfdSAndroid Build Coastguard Workerbpf_text = """ 40*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h> 41*387f9dfdSAndroid Build Coastguard Worker 42*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(args_filename, u32, const char *); 43*387f9dfdSAndroid Build Coastguard Worker 44*387f9dfdSAndroid Build Coastguard Workerint kprobe__sys_open(struct pt_regs *ctx, const char __user *filename) 45*387f9dfdSAndroid Build Coastguard Worker{ 46*387f9dfdSAndroid Build Coastguard Worker u32 pid = bpf_get_current_pid_tgid(); 47*387f9dfdSAndroid Build Coastguard Worker 48*387f9dfdSAndroid Build Coastguard Worker FILTER 49*387f9dfdSAndroid Build Coastguard Worker args_filename.update(&pid, &filename); 50*387f9dfdSAndroid Build Coastguard Worker 51*387f9dfdSAndroid Build Coastguard Worker return 0; 52*387f9dfdSAndroid Build Coastguard Worker}; 53*387f9dfdSAndroid Build Coastguard Worker 54*387f9dfdSAndroid Build Coastguard Workerint kretprobe__sys_open(struct pt_regs *ctx) 55*387f9dfdSAndroid Build Coastguard Worker{ 56*387f9dfdSAndroid Build Coastguard Worker const char **filenamep; 57*387f9dfdSAndroid Build Coastguard Worker int ret = ctx->ax; 58*387f9dfdSAndroid Build Coastguard Worker u32 pid = bpf_get_current_pid_tgid(); 59*387f9dfdSAndroid Build Coastguard Worker 60*387f9dfdSAndroid Build Coastguard Worker filenamep = args_filename.lookup(&pid); 61*387f9dfdSAndroid Build Coastguard Worker if (filenamep == 0) { 62*387f9dfdSAndroid Build Coastguard Worker // missed entry 63*387f9dfdSAndroid Build Coastguard Worker return 0; 64*387f9dfdSAndroid Build Coastguard Worker } 65*387f9dfdSAndroid Build Coastguard Worker 66*387f9dfdSAndroid Build Coastguard Worker bpf_trace_printk("%d %s\\n", ret, *filenamep); 67*387f9dfdSAndroid Build Coastguard Worker args_filename.delete(&pid); 68*387f9dfdSAndroid Build Coastguard Worker 69*387f9dfdSAndroid Build Coastguard Worker return 0; 70*387f9dfdSAndroid Build Coastguard Worker} 71*387f9dfdSAndroid Build Coastguard Worker""" 72*387f9dfdSAndroid Build Coastguard Workerif args.pid: 73*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('FILTER', 74*387f9dfdSAndroid Build Coastguard Worker 'if (pid != %s) { return 0; }' % args.pid) 75*387f9dfdSAndroid Build Coastguard Workerelse: 76*387f9dfdSAndroid Build Coastguard Worker bpf_text = bpf_text.replace('FILTER', '') 77*387f9dfdSAndroid Build Coastguard Workerif debug: 78*387f9dfdSAndroid Build Coastguard Worker print(bpf_text) 79*387f9dfdSAndroid Build Coastguard Worker 80*387f9dfdSAndroid Build Coastguard Worker# initialize BPF 81*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text) 82*387f9dfdSAndroid Build Coastguard Worker 83*387f9dfdSAndroid Build Coastguard Worker# header 84*387f9dfdSAndroid Build Coastguard Workerif args.timestamp: 85*387f9dfdSAndroid Build Coastguard Worker print("%-14s" % ("TIME(s)"), end="") 86*387f9dfdSAndroid Build Coastguard Workerprint("%-6s %-16s %4s %3s %s" % ("PID", "COMM", "FD", "ERR", "PATH")) 87*387f9dfdSAndroid Build Coastguard Worker 88*387f9dfdSAndroid Build Coastguard Workerstart_ts = 0 89*387f9dfdSAndroid Build Coastguard Worker 90*387f9dfdSAndroid Build Coastguard Worker# format output 91*387f9dfdSAndroid Build Coastguard Workerwhile 1: 92*387f9dfdSAndroid Build Coastguard Worker (task, pid, cpu, flags, ts, msg) = b.trace_fields() 93*387f9dfdSAndroid Build Coastguard Worker (ret_s, filename) = msg.split(" ", 1) 94*387f9dfdSAndroid Build Coastguard Worker 95*387f9dfdSAndroid Build Coastguard Worker ret = int(ret_s) 96*387f9dfdSAndroid Build Coastguard Worker if (args.failed and (ret >= 0)): 97*387f9dfdSAndroid Build Coastguard Worker continue 98*387f9dfdSAndroid Build Coastguard Worker 99*387f9dfdSAndroid Build Coastguard Worker # split return value into FD and errno columns 100*387f9dfdSAndroid Build Coastguard Worker if ret >= 0: 101*387f9dfdSAndroid Build Coastguard Worker fd_s = ret 102*387f9dfdSAndroid Build Coastguard Worker err = 0 103*387f9dfdSAndroid Build Coastguard Worker else: 104*387f9dfdSAndroid Build Coastguard Worker fd_s = "-1" 105*387f9dfdSAndroid Build Coastguard Worker err = - ret 106*387f9dfdSAndroid Build Coastguard Worker 107*387f9dfdSAndroid Build Coastguard Worker # print columns 108*387f9dfdSAndroid Build Coastguard Worker if args.timestamp: 109*387f9dfdSAndroid Build Coastguard Worker if start_ts == 0: 110*387f9dfdSAndroid Build Coastguard Worker start_ts = ts 111*387f9dfdSAndroid Build Coastguard Worker print("%-14.9f" % (ts - start_ts), end="") 112*387f9dfdSAndroid Build Coastguard Worker print("%-6d %-16s %4s %3s %s" % (pid, task, fd_s, err, filename)) 113