Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
bcc
Commits
6049d3ff
Commit
6049d3ff
authored
Oct 16, 2016
by
Brendan Gregg
Committed by
4ast
Oct 16, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add ttysnoop (#755)
parent
e822a818
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
264 additions
and
0 deletions
+264
-0
README.md
README.md
+1
-0
man/man8/ttysnoop.8
man/man8/ttysnoop.8
+60
-0
tools/ttysnoop.py
tools/ttysnoop.py
+120
-0
tools/ttysnoop_example.txt
tools/ttysnoop_example.txt
+83
-0
No files found.
README.md
View file @
6049d3ff
...
...
@@ -123,6 +123,7 @@ Examples:
-
tools/
[
tcptop
](
tools/tcptop.py
)
: Summarize TCP send/recv throughput by host. Top for TCP.
[
Examples
](
tools/tcptop_example.txt
)
.
-
tools/
[
tplist
](
tools/tplist.py
)
: Display kernel tracepoints or USDT probes and their formats.
[
Examples
](
tools/tplist_example.txt
)
.
-
tools/
[
trace
](
tools/trace.py
)
: Trace arbitrary functions, with filters.
[
Examples
](
tools/trace_example.txt
)
-
tools/
[
ttysnoop
](
tools/ttysnoop.py
)
: Watch live output from a tty or pts device.
[
Examples
](
tools/ttysnoop_example.txt
)
-
tools/
[
vfscount
](
tools/vfscount.py
)
tools/
[
vfscount.c
](
tools/vfscount.c
)
: Count VFS calls.
[
Examples
](
tools/vfscount_example.txt
)
.
-
tools/
[
vfsstat
](
tools/vfsstat.py
)
tools/
[
vfsstat.c
](
tools/vfsstat.c
)
: Count some VFS calls, with column output.
[
Examples
](
tools/vfsstat_example.txt
)
.
-
tools/
[
wakeuptime
](
tools/wakeuptime.py
)
: Summarize sleep to wakeup time by waker kernel stack.
[
Examples
](
tools/wakeuptime_example.txt
)
.
...
...
man/man8/ttysnoop.8
0 → 100644
View file @
6049d3ff
.TH ttysnoop 8 "2016-02-08" "USER COMMANDS"
.SH NAME
ttysnoop \- Watch output from a tty or pts device. Uses Linux eBPF/bcc.
.SH SYNOPSIS
.B ttysnoop [\-h] [\-C] device
.SH DESCRIPTION
ttysnoop watches a tty or pts device, and prints the same output that is
appearing on that device. It can be used to mirror the output from a shell
session, or the system console.
This works by use of kernel dynamic tracing of the tty_write() function.
This tool will need updating in case that kernel function changes in a future
kernel version.
Since this uses BPF, only the root user can use this tool.
.SH REQUIREMENTS
CONFIG_BPF and bcc.
.SH OPTIONS
.TP
\-C
Don't clear the screen.
.TP
device
Either a path to a tty device (eg, /dev/tty0) or a pts number (eg, the "3"
from /dev/pts/3).
.SH EXAMPLES
.TP
Snoop output from /dev/pts/2
#
.B ttysnoop /dev/pts/2
.TP
Snoop output from /dev/pts/2 (shortcut)
#
.B ttysnoop 2
.TP
Snoop output from the system console
#
.B ttysnoop /dev/console
.TP
Snoop output from /dev/tty0
#
.B ttysnoop /dev/tty0
.SH OVERHEAD
As the rate of tty_write() is expected to be very low (<100/s), the overhead
of this tool 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(1)
tools/ttysnoop.py
0 → 100755
View file @
6049d3ff
#!/usr/bin/python
# @lint-avoid-python-3-compatibility-imports
#
# ttysnoop Watch live output from a tty or pts device.
# For Linux, uses BCC, eBPF. Embedded C.
#
# Due to a limited buffer size (see BUFSIZE), some commands (eg, a vim
# session) are likely to be printed a little messed up.
#
# Copyright (c) 2016 Brendan Gregg.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# Idea: from ttywatcher.
#
# 15-Oct-2016 Brendan Gregg Created this.
from
__future__
import
print_function
from
bcc
import
BPF
import
ctypes
as
ct
from
subprocess
import
call
import
argparse
from
sys
import
argv
import
sys
from
os
import
stat
def
usage
():
print
(
"USAGE: %s [-Ch] {PTS | /dev/ttydev} # try -h for help"
%
argv
[
0
])
exit
()
# arguments
examples
=
"""examples:
./ttysnoop /dev/pts/2 # snoop output from /dev/pts/2
./ttysnoop 2 # snoop output from /dev/pts/2 (shortcut)
./ttysnoop /dev/console # snoop output from the system console
./ttysnoop /dev/tty0 # snoop output from /dev/tty0
"""
parser
=
argparse
.
ArgumentParser
(
description
=
"Snoop output from a pts or tty device, eg, a shell"
,
formatter_class
=
argparse
.
RawDescriptionHelpFormatter
,
epilog
=
examples
)
parser
.
add_argument
(
"-C"
,
"--noclear"
,
action
=
"store_true"
,
help
=
"don't clear the screen"
)
parser
.
add_argument
(
"device"
,
default
=
"-1"
,
help
=
"path to a tty device (eg, /dev/tty0) or pts number"
)
args
=
parser
.
parse_args
()
debug
=
0
if
args
.
device
==
"-1"
:
usage
()
path
=
args
.
device
if
path
.
find
(
'/'
)
!=
0
:
path
=
"/dev/pts/"
+
path
try
:
pi
=
stat
(
path
)
except
:
print
(
"Unable to read device %s. Exiting."
%
path
)
exit
()
# define BPF program
bpf_text
=
"""
#include <uapi/linux/ptrace.h>
#include <linux/fs.h>
#define BUFSIZE 256
struct data_t {
int count;
char buf[BUFSIZE];
};
BPF_PERF_OUTPUT(events);
int kprobe__tty_write(struct pt_regs *ctx, struct file *file,
const char __user *buf, size_t count)
{
if (file->f_inode->i_ino != PTS)
return 0;
// bpf_probe_read() can only use a fixed size, so truncate to count
// in user space:
struct data_t data = {};
bpf_probe_read(&data.buf, BUFSIZE, (void *)buf);
if (count > BUFSIZE)
data.count = BUFSIZE;
else
data.count = count;
events.perf_submit(ctx, &data, sizeof(data));
return 0;
};
"""
bpf_text
=
bpf_text
.
replace
(
'PTS'
,
str
(
pi
.
st_ino
))
if
debug
:
print
(
bpf_text
)
# initialize BPF
b
=
BPF
(
text
=
bpf_text
)
BUFSIZE
=
256
class
Data
(
ct
.
Structure
):
_fields_
=
[
(
"count"
,
ct
.
c_int
),
(
"buf"
,
ct
.
c_char
*
BUFSIZE
)
]
if
not
args
.
noclear
:
call
(
"clear"
)
# process event
def
print_event
(
cpu
,
data
,
size
):
event
=
ct
.
cast
(
data
,
ct
.
POINTER
(
Data
)).
contents
print
(
"%s"
%
event
.
buf
[
0
:
event
.
count
],
end
=
""
)
sys
.
stdout
.
flush
()
# loop with callback to print_event
b
[
"events"
].
open_perf_buffer
(
print_event
)
while
1
:
b
.
kprobe_poll
()
tools/ttysnoop_example.txt
0 → 100644
View file @
6049d3ff
Demonstrations of ttysnoop, the Linux eBPF/bcc version.
ttysnoop watches a tty or pts device, and prints the same output that is
appearing on that device. It can be used to mirror the output from a shell
session, or the system console.
Let's snoop /dev/pts/2:
# ./ttysnoop 2
<screen clears>
date
Sun Oct 16 01:28:47 UTC 2016
# uname -a
Linux bgregg-xenial-bpf-i-xxx 4.8.0-rc4-virtual #1 SMP Wed Aug 31 22:54:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
# df -h
Filesystem Size Used Avail Use% Mounted on
udev 7.4G 0 7.4G 0% /dev
tmpfs 1.5G 89M 1.4G 6% /run
/dev/xvda1 7.8G 4.5G 3.3G 59% /
tmpfs 7.4G 0 7.4G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 7.4G 0 7.4G 0% /sys/fs/cgroup
tmpfs 250M 0 250M 0% /run/shm
/dev/md0 160G 20G 141G 13% /mnt
tmpfs 1.5G 0 1.5G 0% /run/user/0
# ^C
What we're seeing is another shell session. The first line was "date" without
the shell prompt ("#") because we began tracing after the prompt was printed.
The other commands appeared, keystroke by keystroke, as the user was typing
them. Spooky!
Remember to Ctrl-C to exit ttysnoop.
To figure out which pts device number to use, you can check your own with "ps"
and other's with "w". For example:
# ps -p $$
PID TTY TIME CMD
9605 pts/1 00:00:00 bash
# w
01:26:37 up 9 days, 35 min, 2 users, load average: 0.22, 0.22, 0.15
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/1 100.127.65.241 00:39 2.00s 0.33s 0.33s -bash
root pts/2 100.127.65.241 00:40 16.00s 1.06s 1.06s -bash
So I'm pts/1, and there's another session that's pts/2.
This can also snoop tty devices using their full path. Eg, snooping the system
console:
# ./ttysnoop /dev/console
Oct 16 01:32:06 bgregg-xenial-bpf-i-xxx kernel: [780087.407428] bash (9888): drop_caches: 1
Oct 16 01:32:38 bgregg-xenial-bpf-i-xxx snmpd[2708]: Cannot statfs /sys/kernel/debug/tracing: Permission denied
Oct 16 01:33:32 bgregg-xenial-bpf-i-xxx snmpd[2708]: Cannot statfs /sys/kernel/debug/tracing: Permission denied
Oct 16 01:34:26 bgregg-xenial-bpf-i-xxx snmpd[2708]: Cannot statfs /sys/kernel/debug/tracing: Permission denied
^C
Neat!
USAGE:
# ./ttysnoop.py -h
usage: ttysnoop.py [-h] [-C] device
Snoop output from a pts or tty device, eg, a shell
positional arguments:
device path to a tty device (eg, /dev/tty0) or pts number
optional arguments:
-h, --help show this help message and exit
-C, --noclear don't clear the screen
examples:
./ttysnoop /dev/pts/2 # snoop output from /dev/pts/2
./ttysnoop 2 # snoop output from /dev/pts/2 (shortcut)
./ttysnoop /dev/console # snoop output from the system console
./ttysnoop /dev/tty0 # snoop output from /dev/tty0
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment