Skip to content
Snippets Groups Projects
bashreadline.py 1.44 KiB
Newer Older
Brendan Gregg's avatar
Brendan Gregg committed
#
# bashreadline  Print entered bash commands from all running shells.
#               For Linux, uses BCC, eBPF. Embedded C.
#
# This works by tracing the readline() function using a uretprobe (uprobes).
#
# Copyright 2016 Netflix, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 28-Jan-2016    Brendan Gregg   Created this.
# 12-Feb-2016    Allan McAleavy migrated to BPF_PERF_OUTPUT
Brendan Gregg's avatar
Brendan Gregg committed

from __future__ import print_function
from bcc import BPF
from time import strftime

# load BPF program
bpf_text = """
#include <uapi/linux/ptrace.h>

struct str_t {
    u64 pid;
    char str[80];
};

BPF_PERF_OUTPUT(events);

Brendan Gregg's avatar
Brendan Gregg committed
int printret(struct pt_regs *ctx) {
    struct str_t data  = {};
    u32 pid;
Brendan Gregg's avatar
Brendan Gregg committed
        return 0;
    pid = bpf_get_current_pid_tgid();
    data.pid = pid;
    bpf_probe_read(&data.str, sizeof(data.str), (void *)PT_REGS_RC(ctx));
    events.perf_submit(ctx,&data,sizeof(data));
Brendan Gregg's avatar
Brendan Gregg committed

    return 0;
};
"""
Brendan Gregg's avatar
Brendan Gregg committed
b = BPF(text=bpf_text)
b.attach_uretprobe(name="/bin/bash", sym="readline", fn_name="printret")

# header
print("%-9s %-6s %s" % ("TIME", "PID", "COMMAND"))

def print_event(cpu, data, size):
    print("%-9s %-6d %s" % (strftime("%H:%M:%S"), event.pid,
                            event.str.decode('utf-8', 'replace')))

b["events"].open_perf_buffer(print_event)
Brendan Gregg's avatar
Brendan Gregg committed
while 1:
    try:
        b.perf_buffer_poll()
    except KeyboardInterrupt:
        exit()