hack/podmansnoop: print arguments
Update the snoop script to also include the arguments to make the output more useful. ``` $ sudo hack/podmansnoop PCOMM PID PPID AGE(ms) ARGV conmon 14964 14952 1.01 /usr/bin/conmon --version podman 14952 14139 26.07 /usr/bin/podman ps ``` Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
This commit is contained in:
parent
c49de2210c
commit
68d41c68d9
109
hack/podmansnoop
109
hack/podmansnoop
|
@ -1,7 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
|
||||
# Based on the `exitsnoop` scripts at https://github.com/iovisor/bcc/blob/master/tools/exitsnoop.py
|
||||
# Based on the `exitsnoop` script at https://github.com/iovisor/bcc/blob/master/tools/exitsnoop.py
|
||||
# Based on the `execsnoop` script at https://github.com/iovisor/bcc/blob/master/tools/execsnoop.py
|
||||
|
||||
import argparse
|
||||
import os
|
||||
|
@ -11,6 +12,7 @@ import signal
|
|||
import sys
|
||||
|
||||
from bcc import BPF
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
from time import strftime
|
||||
|
||||
|
@ -18,16 +20,16 @@ bpf_src = """
|
|||
#include <uapi/linux/ptrace.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#define ARGSIZE 128
|
||||
#define ARGSIZE 128
|
||||
#define MAXARG 19
|
||||
|
||||
struct data_t {
|
||||
u8 isArgv;
|
||||
u64 start_time;
|
||||
u64 exit_time;
|
||||
u32 pid;
|
||||
u32 tid;
|
||||
u32 ppid;
|
||||
u32 sig_info;
|
||||
char task[TASK_COMM_LEN];
|
||||
char comm[TASK_COMM_LEN];
|
||||
char argv[ARGSIZE];
|
||||
};
|
||||
|
||||
|
@ -42,41 +44,112 @@ TRACEPOINT_PROBE(sched, sched_process_exit)
|
|||
|
||||
data.start_time = task->start_time,
|
||||
data.exit_time = bpf_ktime_get_ns(),
|
||||
data.pid = task->tgid,
|
||||
data.tid = task->pid,
|
||||
data.pid = task->pid,
|
||||
data.ppid = task->real_parent->tgid,
|
||||
data.sig_info = task->exit_code & 0xFF,
|
||||
bpf_get_current_comm(&data.task, sizeof(data.task));
|
||||
bpf_get_current_comm(&data.comm, sizeof(data.comm));
|
||||
|
||||
events.perf_submit(args, &data, sizeof(data));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
|
||||
{
|
||||
bpf_probe_read_user(data->argv, sizeof(data->argv), ptr);
|
||||
events.perf_submit(ctx, data, sizeof(struct data_t));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
|
||||
{
|
||||
const char *argp = NULL;
|
||||
bpf_probe_read_user(&argp, sizeof(argp), ptr);
|
||||
if (argp) {
|
||||
return __submit_arg(ctx, (void *)(argp), data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int syscall__execve(struct pt_regs *ctx,
|
||||
const char __user *filename,
|
||||
const char __user *const __user *__argv,
|
||||
const char __user *const __user *__envp)
|
||||
{
|
||||
|
||||
struct task_struct *task = (typeof(task))bpf_get_current_task();
|
||||
|
||||
struct data_t data = {};
|
||||
data.pid = bpf_get_current_pid_tgid() >> 32;
|
||||
data.isArgv = 1;
|
||||
|
||||
bpf_get_current_comm(&data.comm, sizeof(data.comm));
|
||||
__submit_arg(ctx, (void *)filename, &data);
|
||||
|
||||
// skip first arg, as we submitted filename
|
||||
#pragma unroll
|
||||
for (int i = 1; i < MAXARG; i++) {
|
||||
if (submit_arg(ctx, (void *)&__argv[i], &data) == 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
// handle truncated argument list
|
||||
char ellipsis[] = "...";
|
||||
__submit_arg(ctx, (void *)ellipsis, &data);
|
||||
out:
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_ret_sys_execve(struct pt_regs *ctx)
|
||||
{
|
||||
struct task_struct *task = (typeof(task))bpf_get_current_task();
|
||||
|
||||
struct data_t data = {};
|
||||
data.pid = bpf_get_current_pid_tgid() >> 32;
|
||||
bpf_get_current_comm(&data.comm, sizeof(data.comm));
|
||||
events.perf_submit(ctx, &data, sizeof(data));
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
|
||||
def _print_header():
|
||||
print("%-16s %-7s %-7s %-7s %-7s" %
|
||||
("PCOMM", "PID", "PPID", "TID", "AGE(ms)"))
|
||||
print("%-16s %-7s %-7s %-7s %s" %
|
||||
("PCOMM", "PID", "PPID", "AGE(ms)", "ARGV"))
|
||||
|
||||
buffer = None
|
||||
pidToArgv = defaultdict(list)
|
||||
|
||||
def _print_event(cpu, data, size): # callback
|
||||
"""Print the exit event."""
|
||||
global buffer
|
||||
e = buffer["events"].event(data)
|
||||
|
||||
task = e.task.decode()
|
||||
if task == "3":
|
||||
comm = e.comm.decode()
|
||||
if comm == "3":
|
||||
# For absolutely unknown reasons, 'crun' appears as '3'.
|
||||
task = "crun"
|
||||
comm = "crun"
|
||||
|
||||
if task not in ["podman", "crun", "runc", "conmon", "netavark", "aardvark-dns"]:
|
||||
if e.isArgv:
|
||||
pidToArgv[e.pid].append(e.argv)
|
||||
return
|
||||
|
||||
if comm not in ["podman", "crun", "runc", "conmon", "netavark", "aardvark-dns"]:
|
||||
try:
|
||||
del(pidToArgv[e.pid])
|
||||
except Exception:
|
||||
pass
|
||||
return
|
||||
|
||||
age = (e.exit_time - e.start_time) / 1e6
|
||||
print("%-16s %-7d %-7d %-7d %-7.2f " %
|
||||
(task, e.pid, e.ppid, e.tid, age), end="")
|
||||
argv = b' '.join(pidToArgv[e.pid]).replace(b'\n', b'\\n')
|
||||
print("%-16s %-7d %-7d %-7.2f %s" %
|
||||
(comm, e.pid, e.ppid, age, argv.decode()), end="")
|
||||
print()
|
||||
|
||||
try:
|
||||
del(pidToArgv[e.pid])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def snoop(bpf, event_handler):
|
||||
bpf["events"].open_perf_buffer(event_handler)
|
||||
while True:
|
||||
|
@ -86,6 +159,8 @@ def main():
|
|||
global buffer
|
||||
try:
|
||||
buffer = BPF(text=bpf_src)
|
||||
execve_fnname = buffer.get_syscall_fnname("execve")
|
||||
buffer.attach_kprobe(event=execve_fnname, fn_name="syscall__execve")
|
||||
_print_header()
|
||||
snoop(buffer, _print_event)
|
||||
except KeyboardInterrupt:
|
||||
|
|
Loading…
Reference in New Issue