Skip to content

Commit

Permalink
makes more sense to invert the -X usage
Browse files Browse the repository at this point in the history
  • Loading branch information
brendangregg committed Feb 9, 2016
1 parent e5b4ffe commit 151a43a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 48 deletions.
17 changes: 9 additions & 8 deletions man/man8/execsnoop.8
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
.SH NAME
execsnoop \- Trace new processes via exec() syscalls. Uses Linux eBPF/bcc.
.SH SYNOPSIS
.B execsnoop [\-h] [\-t] [\-X] [\-n NAME]
.B execsnoop [\-h] [\-t] [\-x] [\-n NAME]
.SH DESCRIPTION
execsnoop traces new processes, showing the filename executed, argument
list, and return value (0 for success).
execsnoop traces new processes, showing the filename executed and argument
list.

It works by traces the execve() system call (commonly used exec() variant).
This catches new processes that follow the fork->exec sequence, as well as
Expand All @@ -27,8 +27,8 @@ Print usage message.
\-t
Include a timestamp column.
.TP
\-X
Exclude failed exec()s
\-x
Include failed exec()s
.TP
\-n NAME
Only print command lines matching this name (regex), matched anywhere
Expand All @@ -42,9 +42,9 @@ Trace all exec() syscalls, and include timestamps:
#
.B execsnoop \-t
.TP
Only trace successful exec()s:
Include failed exec()s:
#
.B execsnoop \-X
.B execsnoop \-x
.TP
Only trace exec()s where the filename or arguments contain "mount":
#
Expand All @@ -61,7 +61,8 @@ PID
Process ID
.TP
RET
Return value of exec(). 0 == successs.
Return value of exec(). 0 == successs. Failures are only shown when using the
\-x option.
.TP
ARGS
Filename for the exec(), followed be up to 19 arguments. An ellipsis "..." is
Expand Down
20 changes: 14 additions & 6 deletions tools/execsnoop.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# 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] [-x] [-n NAME]
#
# This currently will print up to a maximum of 19 arguments, plus the process
# name, so 20 fields in total (MAXARG).
Expand All @@ -24,7 +24,7 @@
# arguments
examples = """examples:
./execsnoop # trace all exec() syscalls
./execsnoop -X # only show successful exec()s
./execsnoop -x # include failed exec()s
./execsnoop -t # include timestamps
./execsnoop -n main # only print command lines containing "main"
"""
Expand All @@ -34,8 +34,8 @@
epilog=examples)
parser.add_argument("-t", "--timestamp", action="store_true",
help="include timestamp on output")
parser.add_argument("-X", "--excludefails", action="store_true",
help="exclude failed exec()s")
parser.add_argument("-x", "--fails", action="store_true",
help="include failed exec()s")
parser.add_argument("-n", "--name",
help="only print commands matching this name (regex), any arg")
args = parser.parse_args()
Expand Down Expand Up @@ -125,17 +125,25 @@
# format output
while 1:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
(type, arg) = msg.split(" ", 1)
try:
(type, arg) = msg.split(" ", 1)
except ValueError:
continue

if start_ts == 0:
start_ts = ts

if type == "RET":
if pid not in cmd:
# zero args
cmd[pid] = ""
pcomm[pid] = ""

skip = 0
if args.name:
if not re.search(args.name, cmd[pid]):
skip = 1
if args.excludefails and int(arg) < 0:
if not args.fails and int(arg) < 0:
skip = 1
if skip:
del cmd[pid]
Expand Down
67 changes: 33 additions & 34 deletions tools/execsnoop_example.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,34 @@
Demonstrations of execsnoop, the Linux eBPF/bcc version.


execsnoop traces new processes. For example:
execsnoop traces new processes. For example, tracing the commands invoked when
running "man ls":

# ./execsnoop
# ./execsnoop
PCOMM PID RET ARGS
bash 15887 0 /usr/bin/man ls
preconv 15894 0 /usr/bin/preconv -e UTF-8
man 15896 0 /usr/bin/tbl
man 15897 0 /usr/bin/nroff -mandoc -rLL=169n -rLT=169n -Tutf8
man 15898 0 /usr/bin/pager -s
nroff 15900 0 /usr/bin/locale charmap
nroff 15901 0 /usr/bin/groff -mtty-char -Tutf8 -mandoc -rLL=169n -rLT=169n
groff 15902 0 /usr/bin/troff -mtty-char -mandoc -rLL=169n -rLT=169n -Tutf8
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).

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
that follow the fork->exec sequence, as well as processes that re-exec()
themselves. Some applications fork() but do not exec(), eg, for worker
processes, which won't be included in the execsnoop output.


The -x option can be used to include failed exec()s. For example:

# ./execsnoop -x
PCOMM PID RET ARGS
supervise 9660 0 ./run
supervise 9661 0 ./run
Expand All @@ -21,35 +46,9 @@ run 9661 -2 /usr/local/bin/setuidgid nobody /command/multilog t
supervise 9670 0 ./run
[...]

The output shows the parent process/command name (PCOMM), the PID, the return
value of the exec() (RET), and the filename with arguments (ARGS). The example
above shows various regular system daemon activity, including some failures
(trying to execute a /usr/local/bin/setuidgid, which I just noticed doesn't
exist).

It works by traces the execve() system call (commonly used exec() variant), and
shows details of the arguments and return value. This catches new processes
that follow the fork->exec sequence, as well as processes that re-exec()
themselves. Some applications fork() but do not exec(), eg, for worker
processes, which won't be included in the execsnoop output.


The -X option can be used to only show successful exec()s. For example, tracing
a "man ls":

# ./execsnoop -X
PCOMM PID RET ARGS
bash 15887 0 /usr/bin/man ls
preconv 15894 0 /usr/bin/preconv -e UTF-8
man 15896 0 /usr/bin/tbl
man 15897 0 /usr/bin/nroff -mandoc -rLL=169n -rLT=169n -Tutf8
man 15898 0 /usr/bin/pager -s
nroff 15900 0 /usr/bin/locale charmap
nroff 15901 0 /usr/bin/groff -mtty-char -Tutf8 -mandoc -rLL=169n -rLT=169n
groff 15902 0 /usr/bin/troff -mtty-char -mandoc -rLL=169n -rLT=169n -Tutf8
groff 15903 0 /usr/bin/grotty

This shows the various commands used to process the "man ls" command.
This example shows various regular system daemon activity, including some
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
Expand All @@ -64,19 +63,19 @@ TIME(s) PCOMM PID RET ARGS
USAGE message:

# ./execsnoop -h
usage: execsnoop [-h] [-t] [-X] [-n NAME]
usage: execsnoop [-h] [-t] [-x] [-n NAME]

Trace exec() syscalls

optional arguments:
-h, --help show this help message and exit
-t, --timestamp include timestamp on output
-X, --excludefails exclude failed exec()s
-x, --fails include failed exec()s
-n NAME, --name NAME only print commands matching this name (regex), any
arg

examples:
./execsnoop # trace all exec() syscalls
./execsnoop -X # only show successful exec()s
./execsnoop -x # include failed exec()s
./execsnoop -t # include timestamps
./execsnoop -n main # only print command lines containing "main"

0 comments on commit 151a43a

Please sign in to comment.