Skip to content

Commit

Permalink
tools/execsnoop: add -T option
Browse files Browse the repository at this point in the history
Add a -T option to include a time column on output (HH:MM:SS) and update manpage
and example file accordingly.
  • Loading branch information
boat0 committed Jun 7, 2019
1 parent e8dd701 commit fc72531
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
12 changes: 11 additions & 1 deletion man/man8/execsnoop.8
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
.SH NAME
execsnoop \- Trace new processes via exec() syscalls. Uses Linux eBPF/bcc.
.SH SYNOPSIS
.B execsnoop [\-h] [\-t] [\-x] [\-n NAME] [\-l LINE]
.B execsnoop [\-h] [\-T] [\-t] [\-x] [\-q] [\-n NAME] [\-l LINE]
.B [\-\-max-args MAX_ARGS]
.SH DESCRIPTION
execsnoop traces new processes, showing the filename executed and argument
list.
Expand All @@ -24,6 +25,9 @@ CONFIG_BPF and bcc.
\-h
Print usage message.
.TP
\-T
Include a time column (HH:MM:SS).
.TP
\-t
Include a timestamp column.
.TP
Expand Down Expand Up @@ -69,6 +73,9 @@ Only trace exec()s where argument's line contains "testpkg":
.B execsnoop \-l testpkg
.SH FIELDS
.TP
TIME
Time of exec() return, in HH:MM:SS format.
.TP
TIME(s)
Time of exec() return, in seconds.
.TP
Expand All @@ -78,6 +85,9 @@ Parent process/command name.
PID
Process ID
.TP
PPID
Parent process ID
.TP
RET
Return value of exec(). 0 == successs. Failures are only shown when using the
\-x option.
Expand Down
11 changes: 10 additions & 1 deletion tools/execsnoop.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
# execsnoop Trace new processes via exec() syscalls.
# For Linux, uses BCC, eBPF. Embedded C.
#
# USAGE: execsnoop [-h] [-t] [-x] [-n NAME]
# USAGE: execsnoop [-h] [-T] [-t] [-x] [-q] [-n NAME] [-l LINE]
# [--max-args MAX_ARGS]
#
# This currently will print up to a maximum of 19 arguments, plus the process
# name, so 20 fields in total (MAXARG).
Expand All @@ -24,11 +25,13 @@
import re
import time
from collections import defaultdict
from time import strftime

# arguments
examples = """examples:
./execsnoop # trace all exec() syscalls
./execsnoop -x # include failed exec()s
./execsnoop -T # include time (HH:MM:SS)
./execsnoop -t # include timestamps
./execsnoop -q # add "quotemarks" around arguments
./execsnoop -n main # only print command lines containing "main"
Expand All @@ -38,6 +41,8 @@
description="Trace exec() syscalls",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=examples)
parser.add_argument("-T", "--time", action="store_true",
help="include time column on output (HH:MM:SS)")
parser.add_argument("-t", "--timestamp", action="store_true",
help="include timestamp on output")
parser.add_argument("-x", "--fails", action="store_true",
Expand Down Expand Up @@ -168,6 +173,8 @@
b.attach_kretprobe(event=execve_fnname, fn_name="do_ret_sys_execve")

# header
if args.time:
print("%-9s" % ("TIME"), end="")
if args.timestamp:
print("%-8s" % ("TIME(s)"), end="")
print("%-16s %-6s %-6s %3s %s" % ("PCOMM", "PID", "PPID", "RET", "ARGS"))
Expand Down Expand Up @@ -215,6 +222,8 @@ def print_event(cpu, data, size):
]

if not skip:
if args.time:
printb(b"%-9s" % strftime("%H:%M:%S").encode('ascii'), nl="")
if args.timestamp:
printb(b"%-8.3f" % (time.time() - start_ts), nl="")
ppid = event.ppid if event.ppid > 0 else get_ppid(event.pid)
Expand Down
19 changes: 12 additions & 7 deletions tools/execsnoop_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ groff 15902 0 /usr/bin/troff -mtty-char -mandoc -rLL=169n -rLT=169
groff 15903 0 /usr/bin/grotty

The output shows the parent process/command name (PCOMM), the PID, the return
value of the exec() (RET), and the filename with arguments (ARGS).
value of the exec() (RET), and the filename with arguments (ARGS).

This works by traces the execve() system call (commonly used exec() variant),
and shows details of the arguments and return value. This catches new processes
Expand Down Expand Up @@ -51,13 +51,14 @@ failures (trying to execute a /usr/local/bin/setuidgid, which I just noticed
doesn't exist).


A -t option can be used to include a timestamp column, and a -n option to match
on a name. Regular expressions are allowed.
A -T option can be used to include a time column, a -t option to include a
timestamp column, and a -n option to match on a name. Regular expressions
are allowed.
For example, matching commands containing "mount":

# ./execsnoop -tn mount
TIME(s) PCOMM PID RET ARGS
2.849 mount 18049 0 /bin/mount -p
# ./execsnoop -Ttn mount
TIME TIME(s) PCOMM PID PPID RET ARGS
14:08:23 2.849 mount 18049 1045 0 /bin/mount -p

The -l option can be used to only show command where one of the arguments
matches specified line. The limitation is that we are looking only into first 20
Expand All @@ -79,14 +80,16 @@ rpm 3345452 4146419 0 /bin/rpm -qa testpkg
USAGE message:

# ./execsnoop -h
usage: execsnoop [-h] [-t] [-x] [-n NAME] [-l LINE] [--max-args MAX_ARGS]
usage: execsnoop [-h] [-T] [-t] [-x] [-q] [-n NAME] [-l LINE] [--max-args MAX_ARGS]

Trace exec() syscalls

optional arguments:
-h, --help show this help message and exit
-T, --time include time column on output (HH:MM:SS)
-t, --timestamp include timestamp on output
-x, --fails include failed exec()s
-q, --quote Add quotemarks (") around arguments
-n NAME, --name NAME only print commands matching this name (regex), any
arg
-l LINE, --line LINE only print commands where arg contains this line
Expand All @@ -97,6 +100,8 @@ optional arguments:
examples:
./execsnoop # trace all exec() syscalls
./execsnoop -x # include failed exec()s
./execsnoop -T # include time (HH:MM:SS)
./execsnoop -t # include timestamps
./execsnoop -q # add "quotemarks" around arguments
./execsnoop -n main # only print command lines containing "main"
./execsnoop -l tpkg # only print command where arguments contains "tpkg"

0 comments on commit fc72531

Please sign in to comment.