以下信息参考: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 #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