mirror of
https://github.com/brendangregg/perf-tools.git
synced 2025-12-01 07:26:04 +07:00
execsnoop port (hack) for Linux ftrace
This commit is contained in:
@@ -14,6 +14,7 @@ Using perf_events:
|
||||
Using ftrace:
|
||||
|
||||
- [iosnoop](iosnoop): trace disk I/O with details including latency.
|
||||
- [execsnoop](execsnoop): trace process exec() with command line argument details.
|
||||
- kernel/[funccount](kernel/funccount): count kernel functions that match a string.
|
||||
- kernel/[functrace](kernel/functrace): trace kernel functions that match a string.
|
||||
|
||||
|
||||
46
examples/execsnoop_example.txt
Normal file
46
examples/execsnoop_example.txt
Normal file
@@ -0,0 +1,46 @@
|
||||
Demonstrations of execsnoop.
|
||||
|
||||
Here's execsnoop showing what's really executed by "man ls":
|
||||
|
||||
# ./execsnoop
|
||||
TIME PID PPID ARGS
|
||||
17:52:37 22406 25781 man ls
|
||||
17:52:37 22413 22406 preconv -e UTF-8
|
||||
17:52:37 22416 22406 pager -s
|
||||
17:52:37 22415 22406 /bin/sh /usr/bin/nroff -mandoc -rLL=162n -rLT=162n -Tutf8
|
||||
17:52:37 22414 22406 tbl
|
||||
17:52:37 22419 22418 locale charmap
|
||||
17:52:37 22420 22415 groff -mtty-char -Tutf8 -mandoc -rLL=162n -rLT=162n
|
||||
17:52:37 22421 22420 troff -mtty-char -mandoc -rLL=162n -rLT=162n -Tutf8
|
||||
17:52:37 22422 22420 grotty
|
||||
|
||||
|
||||
These are short-lived processes, where the argument and PPID details are often
|
||||
missed by execsnoop:
|
||||
|
||||
# ./execsnoop
|
||||
TIME PID PPID ARGS
|
||||
18:00:33 26750 1961 multilog <?>
|
||||
18:00:33 26749 1972 multilog <?>
|
||||
18:00:33 26749 1972 multilog <?>
|
||||
18:00:33 26751 ? mkdir <?>
|
||||
18:00:33 26749 1972 multilog <?>
|
||||
18:00:33 26752 ? chown <?>
|
||||
18:00:33 26750 1961 multilog <?>
|
||||
18:00:33 26750 1961 multilog <?>
|
||||
18:00:34 26753 1961 multilog <?>
|
||||
18:00:34 26754 1972 multilog <?>
|
||||
[...]
|
||||
|
||||
This will be fixed in a later version, but likely requires some kernel or
|
||||
tracer changes first (fetching cmdline as the probe fires).
|
||||
|
||||
|
||||
The previous examples were on Linux 3.14 and 3.16 kernels. Here's a 3.2 system
|
||||
I'm running:
|
||||
|
||||
# ./execsnoop
|
||||
ERROR: enabling tracepoint "sched:sched_process_exec" (tracepoint missing in this kernel version?) at ./execsnoop line 78.
|
||||
|
||||
This kernel version is missing the sched_process_exec probe, which is pretty
|
||||
annoying.
|
||||
143
execsnoop
Executable file
143
execsnoop
Executable file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# execsnoop - trace process exec() with arguments.
|
||||
# Written using Linux ftrace.
|
||||
#
|
||||
# This shows the execution of new processes, especially short-lived ones that
|
||||
# can be missed by sampling tools such as top(1).
|
||||
#
|
||||
# USAGE: ./execsnoop [-h] [-n name]
|
||||
#
|
||||
# REQUIREMENTS: FTRACE CONFIG, sched:sched_process_exec tracepoint (you may
|
||||
# already have these on recent kernels), and Perl.
|
||||
#
|
||||
# This traces exec() from the fork()->exec() sequence, which means it won't
|
||||
# catch new processes that only fork(), and, it will catch processes that
|
||||
# re-exec. This instruments sched:sched_process_exec without buffering, and then
|
||||
# in user-space (this program) reads PPID and process arguments asynchronously
|
||||
# from /proc.
|
||||
#
|
||||
# If the process traced is very short-lived, this program may miss reading
|
||||
# arguments and PPID details. In that case, "<?>" and "?" will be printed
|
||||
# respectively. This program is best-effort, and should be improved in the
|
||||
# future when other kernel capabilities are made available.
|
||||
#
|
||||
# From perf-tools: https://github.com/brendangregg/perf-tools
|
||||
#
|
||||
# See the execsnoop(8) man page (in perf-tools) for more info.
|
||||
#
|
||||
# COPYRIGHT: Copyright (c) 2014 Brendan Gregg.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# (http://www.gnu.org/copyleft/gpl.html)
|
||||
#
|
||||
# 07-Jul-2014 Brendan Gregg Created this.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use POSIX qw(strftime);
|
||||
use Getopt::Long;
|
||||
my $tracing = "/sys/kernel/debug/tracing";
|
||||
my $flock = "/var/tmp/.ftrace-lock";
|
||||
my $tpdir = "sched/sched_process_exec";
|
||||
my $tptext = $tpdir; $tptext =~ s/\//:/;
|
||||
local $SIG{INT} = \&cleanup;
|
||||
local $SIG{QUIT} = \&cleanup;
|
||||
local $SIG{TERM} = \&cleanup;
|
||||
local $SIG{PIPE} = \&cleanup;
|
||||
$| = 1;
|
||||
|
||||
### options
|
||||
my ($name, $help);
|
||||
GetOptions("name=s" => \$name,
|
||||
"help" => \$help)
|
||||
or usage();
|
||||
usage() if $help;
|
||||
sub usage {
|
||||
print STDERR "USAGE: execsnoop [-h] [-n name]\n";
|
||||
print STDERR " eg,\n";
|
||||
print STDERR " execsnoop -n ls # show \"ls\" cmds only.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
sub ldie {
|
||||
unlink $flock;
|
||||
die @_;
|
||||
}
|
||||
|
||||
sub writeto {
|
||||
my ($string, $file) = @_;
|
||||
open FILE, ">$file" or return 0;
|
||||
print FILE $string or return 0;
|
||||
close FILE or return 0;
|
||||
}
|
||||
|
||||
### ftrace lock
|
||||
if (-e $flock) {
|
||||
open FLOCK, $flock; my $fpid = <FLOCK>; chomp $fpid; close FLOCK;
|
||||
die "ERROR: ftrace may be in use by PID $fpid ($flock)";
|
||||
}
|
||||
writeto "$$", $flock or die "ERROR: unable to write $flock.";
|
||||
|
||||
### setup and begin tracing
|
||||
chdir "$tracing" or ldie "ERROR: accessing tracing. Root? Kernel has FTRACE?";
|
||||
writeto "nop", "current_tracer" or ldie "ERROR: disabling current_tracer.";
|
||||
writeto "1", "events/$tpdir/enable" or ldie "ERROR: enabling tracepoint " .
|
||||
"\"$tptext\" (tracepoint missing in this kernel version?)";
|
||||
open TPIPE, "trace_pipe" or warn "ERROR: opening trace_pipe.";
|
||||
printf "%-8s %6s %6s %s\n", "TIME", "PID", "PPID", "ARGS";
|
||||
|
||||
while (<TPIPE>) {
|
||||
my ($taskpid, $rest) = split;
|
||||
my ($task, $pid) = $taskpid =~ /(.*)-(\d+)/;
|
||||
|
||||
next if (defined $name and $name ne $task);
|
||||
|
||||
my $args = "$task <?>";
|
||||
if (open CMDLINE, "/proc/$pid/cmdline") {
|
||||
my $arglist = <CMDLINE>;
|
||||
if (defined $arglist) {
|
||||
$arglist =~ s/\000/ /g;
|
||||
$args = $arglist;
|
||||
}
|
||||
close CMDLINE;
|
||||
}
|
||||
|
||||
my $ppid = "?";
|
||||
if (open STAT, "/proc/$pid/stat") {
|
||||
my $fields = <STAT>;
|
||||
if (defined $fields) {
|
||||
$ppid = (split ' ', $fields)[3];
|
||||
}
|
||||
close STAT;
|
||||
}
|
||||
|
||||
my $now = strftime "%H:%M:%S", localtime;
|
||||
printf "%-8s %6s %6s %s\n", $now, $pid, $ppid, $args;
|
||||
}
|
||||
|
||||
### end tracing
|
||||
cleanup();
|
||||
|
||||
sub cleanup {
|
||||
print "\nEnding tracing...\n";
|
||||
close TPIPE;
|
||||
writeto "0", "events/$tpdir/enable" or
|
||||
ldie "ERROR: disabling \"$tptext\"";
|
||||
writeto "", "trace";
|
||||
unlink $flock;
|
||||
exit;
|
||||
}
|
||||
70
man/man8/execsnoop.8
Normal file
70
man/man8/execsnoop.8
Normal file
@@ -0,0 +1,70 @@
|
||||
.TH execsnoop 8 "2014-07-07" "USER COMMANDS"
|
||||
.SH NAME
|
||||
execsnoop \- trace process exec() with arguments. Uses Linux ftrace.
|
||||
.SH SYNOPSIS
|
||||
.B execsnoop
|
||||
[\-h] [\-n name]
|
||||
.SH DESCRIPTION
|
||||
execsnoop traces process execution, showing PID, PPID, and argument details
|
||||
if possible.
|
||||
|
||||
This traces exec() from the fork()->exec() sequence, which means it won't
|
||||
catch new processes that only fork(), and, it will catch processes that
|
||||
re-exec. This instruments sched:sched_process_exec without buffering, and then
|
||||
in user-space (this program) reads PPID and process arguments asynchronously
|
||||
from /proc.
|
||||
|
||||
If the process traced is very short-lived, this program may miss reading
|
||||
arguments and PPID details. In that case, "<?>" and "?" will be printed
|
||||
respectively.
|
||||
|
||||
This program is best-effort (a hack), and should be improved in the future when
|
||||
other kernel capabilities are made available. It may be useful in the meantime.
|
||||
|
||||
Since this uses ftrace, only the root user can use this tool.
|
||||
.SH REQUIREMENTS
|
||||
FTRACE CONFIG, sched:sched_process_exec tracepoint (you may already have these
|
||||
on recent kernels), and Perl.
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
\-n name
|
||||
Only show processes that match this name. This is filtered in user space.
|
||||
.TP
|
||||
\-h
|
||||
Print usage message.
|
||||
.SH FIELDS
|
||||
.TP
|
||||
TIME
|
||||
Time of process exec(): HH:MM:SS.
|
||||
.TP
|
||||
PID
|
||||
Process ID.
|
||||
.TP
|
||||
PPID
|
||||
Parent process ID, if this was able to be read (may be missed for short-lived
|
||||
processes). If it is unable to be read, "?" is printed.
|
||||
.TP
|
||||
ARGS
|
||||
Command line arguments, if these were able to be read in time (may be missed
|
||||
for short-lived processes). If they are unable to be read, "<?>" is printed.
|
||||
.PP
|
||||
.SH OVERHEAD
|
||||
This reads and processes exec() events in user space as they occur. Since the
|
||||
rate of exec() is expected to be low (< 500/s), the overhead is expected to
|
||||
be small or negligible.
|
||||
.PP
|
||||
.SH SOURCE
|
||||
This is from the perf-tools collection.
|
||||
.PP
|
||||
https://github.com/brendangregg/perf-tools
|
||||
.PP
|
||||
Also look under the examples directory for a text 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
|
||||
top(1)
|
||||
Reference in New Issue
Block a user