xref: /aosp_15_r20/external/bcc/tools/sofdsnoop.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
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# sofdsnoop traces file descriptors passed via socket
5*387f9dfdSAndroid Build Coastguard Worker#           For Linux, uses BCC, eBPF. Embedded C.
6*387f9dfdSAndroid Build Coastguard Worker#
7*387f9dfdSAndroid Build Coastguard Worker# USAGE: sofdsnoop
8*387f9dfdSAndroid Build Coastguard Worker#
9*387f9dfdSAndroid Build Coastguard Worker# Copyright (c) 2018 Jiri Olsa.
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# 30-Jul-2018   Jiri Olsa   Created this.
13*387f9dfdSAndroid Build Coastguard Worker
14*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
15*387f9dfdSAndroid Build Coastguard Workerfrom bcc import ArgString, BPF
16*387f9dfdSAndroid Build Coastguard Workerimport os
17*387f9dfdSAndroid Build Coastguard Workerimport argparse
18*387f9dfdSAndroid Build Coastguard Workerfrom datetime import datetime, timedelta
19*387f9dfdSAndroid Build Coastguard Worker
20*387f9dfdSAndroid Build Coastguard Worker# arguments
21*387f9dfdSAndroid Build Coastguard Workerexamples = """examples:
22*387f9dfdSAndroid Build Coastguard Worker    ./sofdsnoop           # trace passed file descriptors
23*387f9dfdSAndroid Build Coastguard Worker    ./sofdsnoop -T        # include timestamps
24*387f9dfdSAndroid Build Coastguard Worker    ./sofdsnoop -p 181    # only trace PID 181
25*387f9dfdSAndroid Build Coastguard Worker    ./sofdsnoop -t 123    # only trace TID 123
26*387f9dfdSAndroid Build Coastguard Worker    ./sofdsnoop -d 10     # trace for 10 seconds only
27*387f9dfdSAndroid Build Coastguard Worker    ./sofdsnoop -n main   # only print process names containing "main"
28*387f9dfdSAndroid Build Coastguard Worker
29*387f9dfdSAndroid Build Coastguard Worker"""
30*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(
31*387f9dfdSAndroid Build Coastguard Worker    description="Trace file descriptors passed via socket",
32*387f9dfdSAndroid Build Coastguard Worker    formatter_class=argparse.RawDescriptionHelpFormatter,
33*387f9dfdSAndroid Build Coastguard Worker    epilog=examples)
34*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-T", "--timestamp", action="store_true",
35*387f9dfdSAndroid Build Coastguard Worker    help="include timestamp on output")
36*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid",
37*387f9dfdSAndroid Build Coastguard Worker    help="trace this PID only")
38*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-t", "--tid",
39*387f9dfdSAndroid Build Coastguard Worker    help="trace this TID only")
40*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-n", "--name",
41*387f9dfdSAndroid Build Coastguard Worker    type=ArgString,
42*387f9dfdSAndroid Build Coastguard Worker    help="only print process names containing this name")
43*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-d", "--duration",
44*387f9dfdSAndroid Build Coastguard Worker    help="total duration of trace in seconds")
45*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
46*387f9dfdSAndroid Build Coastguard Workerdebug = 0
47*387f9dfdSAndroid Build Coastguard Worker
48*387f9dfdSAndroid Build Coastguard WorkerACTION_SEND=0
49*387f9dfdSAndroid Build Coastguard WorkerACTION_RECV=1
50*387f9dfdSAndroid Build Coastguard WorkerMAX_FD=10
51*387f9dfdSAndroid Build Coastguard Worker
52*387f9dfdSAndroid Build Coastguard Workerif args.duration:
53*387f9dfdSAndroid Build Coastguard Worker    args.duration = timedelta(seconds=int(args.duration))
54*387f9dfdSAndroid Build Coastguard Worker
55*387f9dfdSAndroid Build Coastguard Worker# define BPF program
56*387f9dfdSAndroid Build Coastguard Workerbpf_text = """
57*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
58*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/limits.h>
59*387f9dfdSAndroid Build Coastguard Worker#include <linux/sched.h>
60*387f9dfdSAndroid Build Coastguard Worker#include <linux/socket.h>
61*387f9dfdSAndroid Build Coastguard Worker#include <net/sock.h>
62*387f9dfdSAndroid Build Coastguard Worker
63*387f9dfdSAndroid Build Coastguard Worker#define MAX_FD 10
64*387f9dfdSAndroid Build Coastguard Worker#define ACTION_SEND   0
65*387f9dfdSAndroid Build Coastguard Worker#define ACTION_RECV   1
66*387f9dfdSAndroid Build Coastguard Worker
67*387f9dfdSAndroid Build Coastguard Workerstruct val_t {
68*387f9dfdSAndroid Build Coastguard Worker    u64  id;
69*387f9dfdSAndroid Build Coastguard Worker    u64  ts;
70*387f9dfdSAndroid Build Coastguard Worker    int  action;
71*387f9dfdSAndroid Build Coastguard Worker    int  sock_fd;
72*387f9dfdSAndroid Build Coastguard Worker    int  fd_cnt;
73*387f9dfdSAndroid Build Coastguard Worker    int  fd[MAX_FD];
74*387f9dfdSAndroid Build Coastguard Worker    char comm[TASK_COMM_LEN];
75*387f9dfdSAndroid Build Coastguard Worker};
76*387f9dfdSAndroid Build Coastguard Worker
77*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(detach_ptr, u64, struct cmsghdr *);
78*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(sock_fd, u64, int);
79*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(events);
80*387f9dfdSAndroid Build Coastguard Worker
81*387f9dfdSAndroid Build Coastguard Workerstatic void set_fd(int fd)
82*387f9dfdSAndroid Build Coastguard Worker{
83*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
84*387f9dfdSAndroid Build Coastguard Worker
85*387f9dfdSAndroid Build Coastguard Worker    sock_fd.update(&id, &fd);
86*387f9dfdSAndroid Build Coastguard Worker}
87*387f9dfdSAndroid Build Coastguard Worker
88*387f9dfdSAndroid Build Coastguard Workerstatic int get_fd(void)
89*387f9dfdSAndroid Build Coastguard Worker{
90*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
91*387f9dfdSAndroid Build Coastguard Worker    int *fd;
92*387f9dfdSAndroid Build Coastguard Worker
93*387f9dfdSAndroid Build Coastguard Worker    fd = sock_fd.lookup(&id);
94*387f9dfdSAndroid Build Coastguard Worker    return fd ? *fd : -1;
95*387f9dfdSAndroid Build Coastguard Worker}
96*387f9dfdSAndroid Build Coastguard Worker
97*387f9dfdSAndroid Build Coastguard Workerstatic void put_fd(void)
98*387f9dfdSAndroid Build Coastguard Worker{
99*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
100*387f9dfdSAndroid Build Coastguard Worker
101*387f9dfdSAndroid Build Coastguard Worker    sock_fd.delete(&id);
102*387f9dfdSAndroid Build Coastguard Worker}
103*387f9dfdSAndroid Build Coastguard Worker
104*387f9dfdSAndroid Build Coastguard Workerstatic int sent_1(struct pt_regs *ctx, struct val_t *val, int num, void *data)
105*387f9dfdSAndroid Build Coastguard Worker{
106*387f9dfdSAndroid Build Coastguard Worker    val->fd_cnt = min(num, MAX_FD);
107*387f9dfdSAndroid Build Coastguard Worker
108*387f9dfdSAndroid Build Coastguard Worker    if (bpf_probe_read_kernel(&val->fd[0], MAX_FD * sizeof(int), data))
109*387f9dfdSAndroid Build Coastguard Worker        return -1;
110*387f9dfdSAndroid Build Coastguard Worker
111*387f9dfdSAndroid Build Coastguard Worker    events.perf_submit(ctx, val, sizeof(*val));
112*387f9dfdSAndroid Build Coastguard Worker    return 0;
113*387f9dfdSAndroid Build Coastguard Worker}
114*387f9dfdSAndroid Build Coastguard Worker
115*387f9dfdSAndroid Build Coastguard Worker#define SEND_1                                  \
116*387f9dfdSAndroid Build Coastguard Worker    if (sent_1(ctx, &val, num, (void *) data))  \
117*387f9dfdSAndroid Build Coastguard Worker        return 0;                               \
118*387f9dfdSAndroid Build Coastguard Worker                                                \
119*387f9dfdSAndroid Build Coastguard Worker    num -= MAX_FD;                              \
120*387f9dfdSAndroid Build Coastguard Worker    if (num < 0)                                \
121*387f9dfdSAndroid Build Coastguard Worker        return 0;                               \
122*387f9dfdSAndroid Build Coastguard Worker                                                \
123*387f9dfdSAndroid Build Coastguard Worker    data += MAX_FD;
124*387f9dfdSAndroid Build Coastguard Worker
125*387f9dfdSAndroid Build Coastguard Worker#define SEND_2   SEND_1 SEND_1
126*387f9dfdSAndroid Build Coastguard Worker#define SEND_4   SEND_2 SEND_2
127*387f9dfdSAndroid Build Coastguard Worker#define SEND_8   SEND_4 SEND_4
128*387f9dfdSAndroid Build Coastguard Worker#define SEND_260 SEND_8 SEND_8 SEND_8 SEND_2
129*387f9dfdSAndroid Build Coastguard Worker
130*387f9dfdSAndroid Build Coastguard Workerstatic int send(struct pt_regs *ctx, struct cmsghdr *cmsg, int action)
131*387f9dfdSAndroid Build Coastguard Worker{
132*387f9dfdSAndroid Build Coastguard Worker    struct val_t val = { 0 };
133*387f9dfdSAndroid Build Coastguard Worker    int *data, num, fd;
134*387f9dfdSAndroid Build Coastguard Worker    u64 tsp = bpf_ktime_get_ns();
135*387f9dfdSAndroid Build Coastguard Worker
136*387f9dfdSAndroid Build Coastguard Worker    data = (void *) ((char *) cmsg + sizeof(struct cmsghdr));
137*387f9dfdSAndroid Build Coastguard Worker    num  = (cmsg->cmsg_len - sizeof(struct cmsghdr)) / sizeof(int);
138*387f9dfdSAndroid Build Coastguard Worker
139*387f9dfdSAndroid Build Coastguard Worker    val.id      = bpf_get_current_pid_tgid();
140*387f9dfdSAndroid Build Coastguard Worker    val.action  = action;
141*387f9dfdSAndroid Build Coastguard Worker    val.sock_fd = get_fd();
142*387f9dfdSAndroid Build Coastguard Worker    val.ts      = tsp / 1000;
143*387f9dfdSAndroid Build Coastguard Worker
144*387f9dfdSAndroid Build Coastguard Worker    if (bpf_get_current_comm(&val.comm, sizeof(val.comm)) != 0)
145*387f9dfdSAndroid Build Coastguard Worker        return 0;
146*387f9dfdSAndroid Build Coastguard Worker
147*387f9dfdSAndroid Build Coastguard Worker    SEND_260
148*387f9dfdSAndroid Build Coastguard Worker    return 0;
149*387f9dfdSAndroid Build Coastguard Worker}
150*387f9dfdSAndroid Build Coastguard Worker
151*387f9dfdSAndroid Build Coastguard Workerstatic bool allow_pid(u64 id)
152*387f9dfdSAndroid Build Coastguard Worker{
153*387f9dfdSAndroid Build Coastguard Worker    u32 pid = id >> 32; // PID is higher part
154*387f9dfdSAndroid Build Coastguard Worker    u32 tid = id;       // Cast and get the lower part
155*387f9dfdSAndroid Build Coastguard Worker
156*387f9dfdSAndroid Build Coastguard Worker    FILTER
157*387f9dfdSAndroid Build Coastguard Worker
158*387f9dfdSAndroid Build Coastguard Worker    return 1;
159*387f9dfdSAndroid Build Coastguard Worker}
160*387f9dfdSAndroid Build Coastguard Worker
161*387f9dfdSAndroid Build Coastguard Workerint trace_scm_send_entry(struct pt_regs *ctx, struct socket *sock, struct msghdr *hdr)
162*387f9dfdSAndroid Build Coastguard Worker{
163*387f9dfdSAndroid Build Coastguard Worker    struct cmsghdr *cmsg = NULL;
164*387f9dfdSAndroid Build Coastguard Worker
165*387f9dfdSAndroid Build Coastguard Worker    if (!allow_pid(bpf_get_current_pid_tgid()))
166*387f9dfdSAndroid Build Coastguard Worker        return 0;
167*387f9dfdSAndroid Build Coastguard Worker
168*387f9dfdSAndroid Build Coastguard Worker    if (hdr->msg_controllen >= sizeof(struct cmsghdr))
169*387f9dfdSAndroid Build Coastguard Worker        cmsg = hdr->msg_control;
170*387f9dfdSAndroid Build Coastguard Worker
171*387f9dfdSAndroid Build Coastguard Worker    if (!cmsg || (cmsg->cmsg_type != SCM_RIGHTS))
172*387f9dfdSAndroid Build Coastguard Worker        return 0;
173*387f9dfdSAndroid Build Coastguard Worker
174*387f9dfdSAndroid Build Coastguard Worker    return send(ctx, cmsg, ACTION_SEND);
175*387f9dfdSAndroid Build Coastguard Worker};
176*387f9dfdSAndroid Build Coastguard Worker
177*387f9dfdSAndroid Build Coastguard Workerint trace_scm_detach_fds_entry(struct pt_regs *ctx, struct msghdr *hdr)
178*387f9dfdSAndroid Build Coastguard Worker{
179*387f9dfdSAndroid Build Coastguard Worker    struct cmsghdr *cmsg = NULL;
180*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
181*387f9dfdSAndroid Build Coastguard Worker
182*387f9dfdSAndroid Build Coastguard Worker    if (!allow_pid(id))
183*387f9dfdSAndroid Build Coastguard Worker        return 0;
184*387f9dfdSAndroid Build Coastguard Worker
185*387f9dfdSAndroid Build Coastguard Worker    if (hdr->msg_controllen >= sizeof(struct cmsghdr))
186*387f9dfdSAndroid Build Coastguard Worker        cmsg = hdr->msg_control;
187*387f9dfdSAndroid Build Coastguard Worker
188*387f9dfdSAndroid Build Coastguard Worker    if (!cmsg)
189*387f9dfdSAndroid Build Coastguard Worker        return 0;
190*387f9dfdSAndroid Build Coastguard Worker
191*387f9dfdSAndroid Build Coastguard Worker    detach_ptr.update(&id, &cmsg);
192*387f9dfdSAndroid Build Coastguard Worker    return 0;
193*387f9dfdSAndroid Build Coastguard Worker};
194*387f9dfdSAndroid Build Coastguard Worker
195*387f9dfdSAndroid Build Coastguard Workerint trace_scm_detach_fds_return(struct pt_regs *ctx)
196*387f9dfdSAndroid Build Coastguard Worker{
197*387f9dfdSAndroid Build Coastguard Worker    struct cmsghdr **cmsgp;
198*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
199*387f9dfdSAndroid Build Coastguard Worker
200*387f9dfdSAndroid Build Coastguard Worker    if (!allow_pid(id))
201*387f9dfdSAndroid Build Coastguard Worker        return 0;
202*387f9dfdSAndroid Build Coastguard Worker
203*387f9dfdSAndroid Build Coastguard Worker    cmsgp = detach_ptr.lookup(&id);
204*387f9dfdSAndroid Build Coastguard Worker
205*387f9dfdSAndroid Build Coastguard Worker    if (!cmsgp)
206*387f9dfdSAndroid Build Coastguard Worker        return 0;
207*387f9dfdSAndroid Build Coastguard Worker
208*387f9dfdSAndroid Build Coastguard Worker    return send(ctx, *cmsgp, ACTION_RECV);
209*387f9dfdSAndroid Build Coastguard Worker}
210*387f9dfdSAndroid Build Coastguard Worker
211*387f9dfdSAndroid Build Coastguard Workerint syscall__sendmsg(struct pt_regs *ctx, u64 fd, u64 msg, u64 flags)
212*387f9dfdSAndroid Build Coastguard Worker{
213*387f9dfdSAndroid Build Coastguard Worker    struct pt_regs p;
214*387f9dfdSAndroid Build Coastguard Worker
215*387f9dfdSAndroid Build Coastguard Worker    if (!allow_pid(bpf_get_current_pid_tgid()))
216*387f9dfdSAndroid Build Coastguard Worker        return 0;
217*387f9dfdSAndroid Build Coastguard Worker
218*387f9dfdSAndroid Build Coastguard Worker    set_fd(fd);
219*387f9dfdSAndroid Build Coastguard Worker    return 0;
220*387f9dfdSAndroid Build Coastguard Worker}
221*387f9dfdSAndroid Build Coastguard Worker
222*387f9dfdSAndroid Build Coastguard Workerint trace_sendmsg_return(struct pt_regs *ctx)
223*387f9dfdSAndroid Build Coastguard Worker{
224*387f9dfdSAndroid Build Coastguard Worker    if (!allow_pid(bpf_get_current_pid_tgid()))
225*387f9dfdSAndroid Build Coastguard Worker        return 0;
226*387f9dfdSAndroid Build Coastguard Worker
227*387f9dfdSAndroid Build Coastguard Worker    put_fd();
228*387f9dfdSAndroid Build Coastguard Worker    return 0;
229*387f9dfdSAndroid Build Coastguard Worker}
230*387f9dfdSAndroid Build Coastguard Worker
231*387f9dfdSAndroid Build Coastguard Workerint syscall__recvmsg(struct pt_regs *ctx, u64 fd, u64 msg, u64 flags)
232*387f9dfdSAndroid Build Coastguard Worker{
233*387f9dfdSAndroid Build Coastguard Worker    struct pt_regs p;
234*387f9dfdSAndroid Build Coastguard Worker
235*387f9dfdSAndroid Build Coastguard Worker    if (!allow_pid(bpf_get_current_pid_tgid()))
236*387f9dfdSAndroid Build Coastguard Worker        return 0;
237*387f9dfdSAndroid Build Coastguard Worker
238*387f9dfdSAndroid Build Coastguard Worker    fd = fd;
239*387f9dfdSAndroid Build Coastguard Worker
240*387f9dfdSAndroid Build Coastguard Worker    set_fd(fd);
241*387f9dfdSAndroid Build Coastguard Worker    return 0;
242*387f9dfdSAndroid Build Coastguard Worker}
243*387f9dfdSAndroid Build Coastguard Worker
244*387f9dfdSAndroid Build Coastguard Workerint trace_recvmsg_return(struct pt_regs *ctx)
245*387f9dfdSAndroid Build Coastguard Worker{
246*387f9dfdSAndroid Build Coastguard Worker    if (!allow_pid(bpf_get_current_pid_tgid()))
247*387f9dfdSAndroid Build Coastguard Worker        return 0;
248*387f9dfdSAndroid Build Coastguard Worker
249*387f9dfdSAndroid Build Coastguard Worker    put_fd();
250*387f9dfdSAndroid Build Coastguard Worker    return 0;
251*387f9dfdSAndroid Build Coastguard Worker}
252*387f9dfdSAndroid Build Coastguard Worker
253*387f9dfdSAndroid Build Coastguard Worker"""
254*387f9dfdSAndroid Build Coastguard Worker
255*387f9dfdSAndroid Build Coastguard Workerif args.tid:  # TID trumps PID
256*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER',
257*387f9dfdSAndroid Build Coastguard Worker        'if (tid != %s) { return 0; }' % args.tid)
258*387f9dfdSAndroid Build Coastguard Workerelif args.pid:
259*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER',
260*387f9dfdSAndroid Build Coastguard Worker        'if (pid != %s) { return 0; }' % args.pid)
261*387f9dfdSAndroid Build Coastguard Workerelse:
262*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER', '')
263*387f9dfdSAndroid Build Coastguard Worker
264*387f9dfdSAndroid Build Coastguard Worker# initialize BPF
265*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text)
266*387f9dfdSAndroid Build Coastguard Worker
267*387f9dfdSAndroid Build Coastguard Workersyscall_fnname = b.get_syscall_fnname("sendmsg")
268*387f9dfdSAndroid Build Coastguard Workerif BPF.ksymname(syscall_fnname) != -1:
269*387f9dfdSAndroid Build Coastguard Worker    b.attach_kprobe(event=syscall_fnname, fn_name="syscall__sendmsg")
270*387f9dfdSAndroid Build Coastguard Worker    b.attach_kretprobe(event=syscall_fnname, fn_name="trace_sendmsg_return")
271*387f9dfdSAndroid Build Coastguard Worker
272*387f9dfdSAndroid Build Coastguard Workersyscall_fnname = b.get_syscall_fnname("recvmsg")
273*387f9dfdSAndroid Build Coastguard Workerif BPF.ksymname(syscall_fnname) != -1:
274*387f9dfdSAndroid Build Coastguard Worker    b.attach_kprobe(event=syscall_fnname, fn_name="syscall__recvmsg")
275*387f9dfdSAndroid Build Coastguard Worker    b.attach_kretprobe(event=syscall_fnname, fn_name="trace_recvmsg_return")
276*387f9dfdSAndroid Build Coastguard Worker
277*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="__scm_send", fn_name="trace_scm_send_entry")
278*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="scm_detach_fds", fn_name="trace_scm_detach_fds_entry")
279*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="scm_detach_fds", fn_name="trace_scm_detach_fds_return")
280*387f9dfdSAndroid Build Coastguard Worker
281*387f9dfdSAndroid Build Coastguard Workerinitial_ts = 0
282*387f9dfdSAndroid Build Coastguard Worker
283*387f9dfdSAndroid Build Coastguard Worker# header
284*387f9dfdSAndroid Build Coastguard Workerif args.timestamp:
285*387f9dfdSAndroid Build Coastguard Worker    print("%-14s" % ("TIME(s)"), end="")
286*387f9dfdSAndroid Build Coastguard Workerprint("%-6s %-6s %-16s %-25s %-5s %s" %
287*387f9dfdSAndroid Build Coastguard Worker      ("ACTION", "TID", "COMM", "SOCKET", "FD", "NAME"))
288*387f9dfdSAndroid Build Coastguard Worker
289*387f9dfdSAndroid Build Coastguard Workerdef get_file(pid, fd):
290*387f9dfdSAndroid Build Coastguard Worker    proc = "/proc/%d/fd/%d" % (pid, fd)
291*387f9dfdSAndroid Build Coastguard Worker    try:
292*387f9dfdSAndroid Build Coastguard Worker        return os.readlink(proc)
293*387f9dfdSAndroid Build Coastguard Worker    except OSError as err:
294*387f9dfdSAndroid Build Coastguard Worker        return "N/A"
295*387f9dfdSAndroid Build Coastguard Worker
296*387f9dfdSAndroid Build Coastguard Worker# process event
297*387f9dfdSAndroid Build Coastguard Workerdef print_event(cpu, data, size):
298*387f9dfdSAndroid Build Coastguard Worker    event = b["events"].event(data)
299*387f9dfdSAndroid Build Coastguard Worker    tid = event.id & 0xffffffff;
300*387f9dfdSAndroid Build Coastguard Worker
301*387f9dfdSAndroid Build Coastguard Worker    cnt = min(MAX_FD, event.fd_cnt);
302*387f9dfdSAndroid Build Coastguard Worker
303*387f9dfdSAndroid Build Coastguard Worker    if args.name and bytes(args.name) not in event.comm:
304*387f9dfdSAndroid Build Coastguard Worker        return
305*387f9dfdSAndroid Build Coastguard Worker
306*387f9dfdSAndroid Build Coastguard Worker    for i in range(0, cnt):
307*387f9dfdSAndroid Build Coastguard Worker        global initial_ts
308*387f9dfdSAndroid Build Coastguard Worker
309*387f9dfdSAndroid Build Coastguard Worker        if not initial_ts:
310*387f9dfdSAndroid Build Coastguard Worker            initial_ts = event.ts
311*387f9dfdSAndroid Build Coastguard Worker
312*387f9dfdSAndroid Build Coastguard Worker        if args.timestamp:
313*387f9dfdSAndroid Build Coastguard Worker            delta = event.ts - initial_ts
314*387f9dfdSAndroid Build Coastguard Worker            print("%-14.9f" % (float(delta) / 1000000), end="")
315*387f9dfdSAndroid Build Coastguard Worker
316*387f9dfdSAndroid Build Coastguard Worker        print("%-6s %-6d %-16s " %
317*387f9dfdSAndroid Build Coastguard Worker              ("SEND" if event.action == ACTION_SEND else "RECV",
318*387f9dfdSAndroid Build Coastguard Worker               tid, event.comm.decode()), end = '')
319*387f9dfdSAndroid Build Coastguard Worker
320*387f9dfdSAndroid Build Coastguard Worker        sock = "%d:%s" % (event.sock_fd, get_file(tid, event.sock_fd))
321*387f9dfdSAndroid Build Coastguard Worker        print("%-25s " % sock, end = '')
322*387f9dfdSAndroid Build Coastguard Worker
323*387f9dfdSAndroid Build Coastguard Worker        fd = event.fd[i]
324*387f9dfdSAndroid Build Coastguard Worker        fd_file = get_file(tid, fd) if event.action == ACTION_SEND else ""
325*387f9dfdSAndroid Build Coastguard Worker        print("%-5d %s" % (fd, fd_file))
326*387f9dfdSAndroid Build Coastguard Worker
327*387f9dfdSAndroid Build Coastguard Worker# loop with callback to print_event
328*387f9dfdSAndroid Build Coastguard Workerb["events"].open_perf_buffer(print_event, page_cnt=64)
329*387f9dfdSAndroid Build Coastguard Workerstart_time = datetime.now()
330*387f9dfdSAndroid Build Coastguard Workerwhile not args.duration or datetime.now() - start_time < args.duration:
331*387f9dfdSAndroid Build Coastguard Worker    try:
332*387f9dfdSAndroid Build Coastguard Worker        b.perf_buffer_poll(timeout=1000)
333*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
334*387f9dfdSAndroid Build Coastguard Worker        exit()
335