Demonstrations of execsnoop, the Linux eBPF/bcc version.


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

# ./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
mkdir            9662     0 /bin/mkdir -p ./main
run              9663     0 ./run
chown            9664     0 /bin/chown nobody:nobody ./main
run              9665     0 /bin/mkdir -p ./main
supervise        9667     0 ./run
run              9660    -2 /usr/local/bin/setuidgid nobody /command/multilog t ./main
chown            9668     0 /bin/chown nobody:nobody ./main
run              9666     0 /bin/chmod 0777 main
run              9663    -2 /usr/local/bin/setuidgid nobody /command/multilog t ./main
run              9669     0 /bin/mkdir -p ./main
run              9661    -2 /usr/local/bin/setuidgid nobody /command/multilog t ./main
supervise        9670     0 ./run
[...]

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
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

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
arguments of the command. For example, matching all command where one of the argument
is "testpkg":

# ./execsnoop.py -l testpkg
PCOMM            PID    PPID   RET ARGS
service          3344535 4146419   0 /usr/sbin/service testpkg status
systemctl        3344535 4146419   0 /bin/systemctl status testpkg.service
yum              3344856 4146419   0 /usr/local/bin/yum remove testpkg
python           3344856 4146419   0 /usr/local/bin/python /usr/local/bin/yum remove testpkg
yum              3344856 4146419   0 /usr/bin/yum remove testpkg
yum              3345086 4146419   0 /usr/local/bin/yum install testpkg
python           3345086 4146419   0 /usr/local/bin/python /usr/local/bin/yum install testpkg
yum              3345086 4146419   0 /usr/bin/yum install testpkg
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]

Trace exec() syscalls

optional arguments:
  -h, --help            show this help message and exit
  -t, --timestamp       include timestamp on output
  -x, --fails           include failed exec()s
  -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
                        (regex)
  --max-args MAX_ARGS   maximum number of arguments parsed and displayed,
                        defaults to 20

examples:
    ./execsnoop           # trace all exec() syscalls
    ./execsnoop -x        # include failed exec()s
    ./execsnoop -t        # include timestamps
    ./execsnoop -n main   # only print command lines containing "main"
    ./execsnoop -l tpkg   # only print command where arguments contains "tpkg"
