以下信息参考:https://blog.51cto.com/liuzhengwei521/2419139
execsnoop-专门用于为追踪短时进程(瞬时进程)设计的工具;
它通过 ftrace 实时监控进程的 exec() 行为,并输出短时进程的基本信息,包括进程 PID、父进程 PID、命令行参数以及执行的结果。
github地址:https://github.com/brendangregg/perf-tools/blob/master/execsnoop
如何安装使用:将上面的github的内容复制,然后写入execsnoop文件,并且加上x权限即可;
execsnoop使用方法:
./execsnoop
execsnoop文件内容如下:
#!/bin/bash
#
#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 [-hrt] [-n name]
#
#REQUIREMENTS: FTRACE and KPROBE CONFIG, sched:sched_process_fork tracepoint,
#and either the sys_execve, stub_execve or do_execve kernel function. You may
#already have these on recent kernels. And awk.
#
#This traces exec() from the fork()->exec() sequence, which means it won't
#catch new processes that only fork(). With the -r option, it will also catch
#processes that re-exec. It makes a best-effort attempt to retrieve the program
#arguments and PPID; if these are unavailable, 0 and "[?]" are printed
#respectively. There is also a limit to the number of arguments printed (by
#default, 8), which can be increased using -a.
#
#This implementation is designed to work on older kernel versions, and without
#kernel debuginfo. It works by dynamic tracing an execve kernel function to
#read the arguments from the %si register. The sys_execve function is tried
#first, then stub_execve and do_execve. The sched:sched_process_fork
#tracepoint is used to get the PPID. This program is a workaround that should be
#improved in the future when other kernel capabilities are made available. If
#you need a more reliable tool now, then consider other tracing alternatives
#(eg, SystemTap). This tool is really a proof of concept to see what ftrace can
#currently do.
#
#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-2014Brendan GreggCreated this.
### default variables
tracing=/sys/kernel/debug/tracing
flock=/var/tmp/.ftrace-lock;wroteflock=0
opt_duration=0;duration=;opt_name=0;name=;opt_time=0;opt_reexec=0
opt_argc=0;argc=8;max_argc=16;ftext=
trap':'INT QUIT TERM PIPE HUP#sends execution to end tracing section
functionusage{
cat<<-END>&2
USAGE: execsnoop [-hrt] [-a argc] [-d secs] [name]
-d seconds # trace duration, and use buffers
-a argc # max args to show (default 8)
-r # include re-execs
-t # include time (seconds)
-h # this usage message
name # process name to match (REs allowed)
eg,
execsnoop # watch exec()s live (unbuffered)
execsnoop -d 1 # trace 1 sec (buffered)
execsnoop grep # trace process names containing grep
execsnoop 'udevd$' # process names ending in "udevd"
See the man page and example file for more info.
END
exit
}
functionwarn{
if!eval"$@";then
echo>&2"WARNING: command failed\"$@\""
fi
}
functionend{
#disable tracing
echo2>/dev/null
echo"Ending tracing..."2>/dev/null
cd$tracing
warn"echo 0 > events/kprobes/$kname/enable"
warn"echo 0 > events/sched/sched_process_fork/enable"
warn"echo -:$kname>> kprobe_events"
warn"echo > trace"
((wroteflock))&&warn"rm$flock"
}
functiondie{
echo>&2"$@"
exit1
}
functionedie{
#die with a quiet end()
echo>&2"$@"
exec>/dev/null2>&1
end
exit1
}
### process options
whilegetoptsa:d:hrt opt
do
case$optin
a)opt_argc=1;argc=$OPTARG;;
d)opt_duration=1;duration=$OPTARG;;
r) opt_reexec=1 ;;
t) opt_time=1 ;;
h|?)usage ;;
esac
done
shift$(($OPTIND-1))
if(($#));then
opt_name=1
name=$1
shift
fi
(($#))&&usage
### option logic
((opt_pid&&opt_name))&&die"ERROR: use either -p or -n."
((opt_pid))&&ftext="issued by PID$pid"
((opt_name))&&ftext="issued by process name\"$name\""
((opt_file))&&ftext="$ftextfor filenames containing\"$file\""
((opt_argc&&argc>max_argc))&&die"ERROR: max -a argc is$max_argc."
if((opt_duration));then
echo"Tracing exec()s$ftextfor$durationseconds (buffered)..."
else
echo"Tracing exec()s$ftext. Ctrl-C to end."
fi
### select awk
if((opt_duration));then
[[-x/usr/bin/mawk ]]&&awk=mawk||awk=awk
else
#workarounds for mawk/gawk fflush behavior
if[[-x/usr/bin/gawk ]];then
awk=gawk
elif[[-x/usr/bin/mawk ]];then
awk="mawk -W interactive"
else
awk=awk
fi
fi
### check permissions
cd$tracing||die"ERROR: accessing tracing. Root user? Kernel has FTRACE?
debugfs mounted? (mount -t debugfs debugfs /sys/kernel/debug)"
### ftrace lock
[[-e$flock]]&&die"ERROR: ftrace may be in use by PID$(cat$flock)$flock"
echo$$>$flock||die"ERROR: unable to write$flock."
wroteflock=1
### build probe
if[[-x/usr/bin/getconf ]];then
bits=$(getconf LONG_BIT)
else
bits=64
[[$(uname -m)==i*]]&&bits=32
fi
((offset=bits/8))
functionmakeprobe{
func=$1
kname=execsnoop_$func
kprobe="p:$kname$func"
i=0
while((i<argc+1));do
#p:kname do_execve +0(+0(%si)):string +0(+8(%si)):string ...
kprobe="$kprobe+0(+$((i*offset))(%si)):string"
((i++))
done
}
#try in this order: sys_execve, stub_execve, do_execve
makeprobe sys_execve
### setup and begin tracing
echonop>current_tracer
if!echo$kprobe>>kprobe_events2>/dev/null;then
makeprobe stub_execve
if!echo$kprobe>>kprobe_events2>/dev/null;then
makeprobe do_execve
if!echo$kprobe>>kprobe_events2>/dev/null;then
edie"ERROR: adding a kprobe for execve. Exiting."
fi
fi
fi
if!echo1>events/kprobes/$kname/enable;then
edie"ERROR: enabling kprobe for execve. Exiting."
fi
if!echo1>events/sched/sched_process_fork/enable;then
edie"ERROR: enabling sched:sched_process_fork tracepoint. Exiting."
fi
echo"Instrumenting$func"
((opt_time))&&printf"%-16s""TIMEs"
printf"%6s %6s %s\n""PID""PPID""ARGS"
#
#Determine output format. It may be one of the following (newest first):
#TASK-PID CPU# |||| TIMESTAMP FUNCTION
#TASK-PID CPU# TIMESTAMP FUNCTION
#To differentiate between them, the number of header fields is counted,
#and an offset set, to skip the extra column when needed.
#
offset=$($awk'BEGIN { o = 0; }
$1 == "#" && $2 ~ /TASK/ && NF == 6 { o = 1; }
$2 ~ /TASK/ { print o; exit }'trace)
### print trace buffer
warn"echo > trace"
(if((opt_duration));then
#wait then dump buffer
sleep$duration
cat -v trace
else
#print buffer live
cat -v trace_pipe
fi)|$awk-v o=$offset-v opt_name=$opt_name-v name=$name\
-v opt_duration=$opt_duration-v opt_time=$opt_time-v kname=$kname\
-v opt_reexec=$opt_reexec'
# common fields
$1 != "#" {
# task name can contain dashes
comm = pid = $1
sub(/-[0-9][0-9]*/, "", comm)
sub(/.*-/, "", pid)
}
$1 != "#" && $(4+o) ~ /sched_process_fork/ {
cpid=$0
sub(/.* child_pid=/, "", cpid)
sub(/ .*/, "", cpid)
getppid[cpid] = pid
delete seen[pid]
}
$1 != "#" && $(4+o) ~ kname {
if (seen[pid])
next
if (opt_name && comm !~ name)
next
#
# examples:
# ... arg1="/bin/echo" arg2="1" arg3="2" arg4="3" ...
# ... arg1="sleep" arg2="2" arg3=(fault) arg4="" ...
# ... arg1="" arg2=(fault) arg3="" arg4="" ...
# the last example is uncommon, and may be a race.
#
if ($0 ~ /arg1=""/) {
args = comm " [?]"
} else {
args=$0
sub(/ arg[0-9]*=\(fault\).*/, "", args)
sub(/.*arg1="/, "", args)
gsub(/" arg[0-9]*="/, " ", args)
sub(/"$/, "", args)
if ($0 !~ /\(fault\)/)
args = args " [...]"
}
if (opt_time) {
time = $(3+o); sub(":", "", time)
printf "%-16s ", time
}
printf "%6s %6d %s\n", pid, getppid[pid], args
if (!opt_duration)
fflush()
if (!opt_reexec) {
seen[pid] = 1
delete getppid[pid]
}
}
$0 ~ /LOST.*EVENT[S]/ { print "WARNING: " $0 > "/dev/stderr" }
'
### end tracing
end