From aa87997d21e5c1a6a20e2c96dd25eb92adc8e85d Mon Sep 17 00:00:00 2001 From: Brendan Gregg Date: Thu, 28 Jan 2016 22:43:37 -0800 Subject: [PATCH] bashreadline --- README.md | 1 + man/man8/bashreadline.8 | 48 ++++++++++++++++++++++++++++++++++++++++++ tools/bashreadline.py | 43 +++++++++++++++++++++++++++++++++++++ tools/bashreadline_example.txt | 21 ++++++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 man/man8/bashreadline.8 create mode 100755 tools/bashreadline.py create mode 100644 tools/bashreadline_example.txt diff --git a/README.md b/README.md index 0eae60c..7d88ee1 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Examples: Tools: +- tools/[bashreadline](tools/bashreadline.py): Print entered bash commands system wide. [Examples](tools/bashreadline_example.txt). - tools/[biolatency](tools/biolatency.py): Summarize block device I/O latency as a histogram. [Examples](tools/biolatency_example.txt). - tools/[biosnoop](tools/biosnoop.py): Trace block device I/O with PID and latency. [Examples](tools/biosnoop_example.txt). - tools/[funccount](tools/funccount.py): Count kernel function calls. [Examples](tools/funccount_example.txt). diff --git a/man/man8/bashreadline.8 b/man/man8/bashreadline.8 new file mode 100644 index 0000000..c5f93e4 --- /dev/null +++ b/man/man8/bashreadline.8 @@ -0,0 +1,48 @@ +.TH bashreadline 8 "2016-01-28" "USER COMMANDS" +.SH NAME +bashreadline \- Print entered bash commands system wide. Uses Linux eBPF/bcc. +.SH SYNOPSIS +.B bashreadline +.SH DESCRIPTION +bashreadline traces the return of the readline() function using uprobes, to +show the bash commands that were entered interactively, system wide. The +entered command may fail: this is just showing what was entered. + +This program is also a basic example of eBPF/bcc and uprobes. + +Since this uses BPF, only the root user can use this tool. +.SH REQUIREMENTS +CONFIG_BPF and bcc. +.SH EXAMPLES +.TP +Trace bash commands system wide: +# +.B bashreadline +.SH FIELDS +.TP +TIME +Time of the command (HH:MM:SS). +.TP +PID +Process ID of the bash shell. +.TP +COMMAND +Entered command. +.SH OVERHEAD +As the rate of interactive bash commands is expected to be very low (<<100/s), +the overhead of this program is expected to be negligible. +.SH SOURCE +This is from bcc. +.IP +https://github.com/iovisor/bcc +.PP +Also look in the bcc distribution for a companion _examples.txt file containing +example usage, output, and commentary for this tool. +.SH OS +Linux +.SH STABILITY +Unstable - in development. +.SH AUTHOR +Brendan Gregg +.SH SEE ALSO +opensnoop(8) diff --git a/tools/bashreadline.py b/tools/bashreadline.py new file mode 100755 index 0000000..464dfda --- /dev/null +++ b/tools/bashreadline.py @@ -0,0 +1,43 @@ +#!/usr/bin/python +# +# 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. + +from __future__ import print_function +from bcc import BPF +from time import strftime + +# load BPF program +bpf_text = """ +#include +int printret(struct pt_regs *ctx) { + if (!ctx->ax) + return 0; + + char str[80] = {}; + bpf_probe_read(&str, sizeof(str), (void *)ctx->ax); + bpf_trace_printk("%s\\n", &str); + + return 0; +}; +""" +b = BPF(text=bpf_text) +b.attach_uretprobe(name="/bin/bash", sym="readline", fn_name="printret") + +# header +print("%-9s %-6s %s" % ("TIME", "PID", "COMMAND")) + +# format output +while 1: + try: + (task, pid, cpu, flags, ts, msg) = b.trace_fields() + except ValueError: + continue + print("%-9s %-6d %s" % (strftime("%H:%M:%S"), pid, msg)) diff --git a/tools/bashreadline_example.txt b/tools/bashreadline_example.txt new file mode 100644 index 0000000..861a89b --- /dev/null +++ b/tools/bashreadline_example.txt @@ -0,0 +1,21 @@ +Demonstrations of bashreadline, the Linux eBPF/bcc version. + + +This prints bash commands from all running bash shells on the system. For +example: + +# ./bashreadline +TIME PID COMMAND +05:28:25 21176 ls -l +05:28:28 21176 date +05:28:35 21176 echo hello world +05:28:43 21176 foo this command failed +05:28:45 21176 df -h +05:29:04 3059 echo another shell +05:29:13 21176 echo first shell again + +The entered command may fail. This is just showing what command lines were +entered interactively for bash to process. + +It works by tracing the return of the readline() function using uprobes +(specifically a uretprobe). -- 2.7.4