Merge pull request #56 from goldshtn/filter-pid

kprobe, opensnoop, tpoint, uprobe: Make -p switch respect all process' threads
This commit is contained in:
Brendan Gregg
2017-09-05 17:00:06 -07:00
committed by GitHub
12 changed files with 113 additions and 47 deletions

View File

@@ -346,10 +346,11 @@ This makes use of the kernel options/stacktrace feature.
Use -h to print the USAGE message:
# ./kprobe -h
USAGE: kprobe [-FhHsv] [-d secs] [-p PID] kprobe_definition [filter]
USAGE: kprobe [-FhHsv] [-d secs] [-p PID] [-L TID] kprobe_definition [filter]
-F # force. trace despite warnings.
-d seconds # trace duration, and use buffers
-p PID # PID to match on I/O issue
-p PID # PID to match on events
-L TID # thread id to match on events
-v # view format file (don't trace)
-H # include column headers
-s # show kernel stack traces

View File

@@ -28,10 +28,11 @@ The first several lines show opensnoop catching itself initializing.
Use -h to print the USAGE message:
# ./opensnoop -h
USAGE: opensnoop [-htx] [-d secs] [-p PID] [-n name] [filename]
USAGE: opensnoop [-htx] [-d secs] [-p PID] [-T TID] [-n name] [filename]
-d seconds # trace duration, and use buffers
-n name # process name to match on I/O issue
-p PID # PID to match on I/O issue
-n name # process name to match on open
-p PID # PID to match on open
-L TID # thread id to match on open
-t # include time (seconds)
-x # only show failed opens
-h # this usage message

View File

@@ -184,10 +184,11 @@ making it a read:
Use -h to print the USAGE message:
# ./tpoint -h
USAGE: tpoint [-hHsv] [-d secs] [-p PID] tracepoint [filter]
USAGE: tpoint [-hHsv] [-d secs] [-p PID] [-L TID] tracepoint [filter]
tpoint -l
-d seconds # trace duration, and use buffers
-p PID # PID to match on I/O issue
-p PID # PID to match on events
-L TID # thread id to match on events
-v # view format file (don't trace)
-H # include column headers
-l # list all tracepoints

View File

@@ -286,12 +286,13 @@ a different method of stack walking.
Use -h to print the USAGE message:
# ./uprobe -h
USAGE: uprobe [-FhHsv] [-d secs] [-p PID] {-l target |
USAGE: uprobe [-FhHsv] [-d secs] [-p PID] [-L TID] {-l target |
uprobe_definition [filter]}
-F # force. trace despite warnings.
-d seconds # trace duration, and use buffers
-l target # list functions from this executable
-p PID # PID to match on I/O issue
-p PID # PID to match on events
-L TID # thread id to match on events
-v # view format file (don't trace)
-H # include column headers
-s # show user stack traces

View File

@@ -9,7 +9,7 @@
# the probe alias is optional (it will become to kprobe:<funcname> if not
# specified).
#
# USAGE: ./kprobe [-FhHsv] [-d secs] [-p pid] kprobe_definition [filter]
# USAGE: ./kprobe [-FhHsv] [-d secs] [-p pid] [-L tid] kprobe_definition [filter]
#
# Run "kprobe -h" for full usage.
#
@@ -50,16 +50,18 @@
### default variables
tracing=/sys/kernel/debug/tracing
flock=/var/tmp/.ftrace-lock; wroteflock=0
opt_duration=0; duration=; opt_pid=0; pid=; opt_filter=0; filter=
opt_view=0; opt_headers=0; opt_stack=0; dmesg=2; debug=0; opt_force=0
opt_duration=0; duration=; opt_pid=0; pid=; opt_tid=0; tid=
opt_filter=0; filter=; opt_view=0; opt_headers=0; opt_stack=0; dmesg=2
debug=0; opt_force=0
trap ':' INT QUIT TERM PIPE HUP # sends execution to end tracing section
function usage {
cat <<-END >&2
USAGE: kprobe [-FhHsv] [-d secs] [-p PID] kprobe_definition [filter]
USAGE: kprobe [-FhHsv] [-d secs] [-p PID] [-L TID] kprobe_definition [filter]
-F # force. trace despite warnings.
-d seconds # trace duration, and use buffers
-p PID # PID to match on events
-L TID # thread id to match on events
-v # view format file (don't trace)
-H # include column headers
-s # show kernel stack traces
@@ -125,12 +127,13 @@ function edie {
}
### process options
while getopts Fd:hHp:sv opt
while getopts Fd:hHp:L:sv opt
do
case $opt in
F) opt_force=1 ;;
d) opt_duration=1; duration=$OPTARG ;;
p) opt_pid=1; pid=$OPTARG ;;
L) opt_tid=1; tid=$OPTARG ;;
H) opt_headers=1 ;;
s) opt_stack=1 ;;
v) opt_view=1 ;;
@@ -147,12 +150,21 @@ if (( $# )); then
fi
### option logic
(( opt_pid && opt_filter )) && die "ERROR: use either -p or a filter."
(( opt_pid + opt_filter + opt_tid > 1 )) && \
die "ERROR: use at most one of -p, -L, or filter."
(( opt_duration && opt_view )) && die "ERROR: use either -d or -v."
if (( opt_pid )); then
# convert to filter
opt_filter=1
filter="common_pid == $pid"
# ftrace common_pid is thread id from user's perspective
for tid in /proc/$pid/task/*; do
filter="$filter || common_pid == ${tid##*/}"
done
filter=${filter:3} # trim leading ' || ' (four characters)
fi
if (( opt_tid )); then
opt_filter=1
filter="common_pid == $tid"
fi
if [[ "$kprobe" != p:* && "$kprobe" != r:* ]]; then
echo >&2 "ERROR: invalid kprobe definition (should start with p: or r:)"

View File

@@ -3,7 +3,7 @@
kprobe \- trace a given kprobe definition. Kernel dynamic tracing. Uses Linux ftrace.
.SH SYNOPSIS
.B kprobe
[\-FhHsv] [\-d secs] [\-p PID] kprobe_definition [filter]
[\-FhHsv] [\-d secs] [\-p PID] [\-L TID] kprobe_definition [filter]
.SH DESCRIPTION
This will create, trace, then destroy a given kprobe definition. See
Documentation/trace/kprobetrace.txt in the Linux kernel source for the
@@ -60,6 +60,9 @@ for use in a custom filter.
\-p PID
Only trace kernel functions when this process ID is on-CPU.
.TP
\-L TID
Only trace kernel functions when this thread ID is on-CPU.
.TP
kprobe_definition
A full kprobe definition, as documented by Documentation/trace/kprobetrace.txt
in the Linux kernel source. Note that the probe alias name is optional with

View File

@@ -3,7 +3,7 @@
opensnoop \- trace open() syscalls with file details. Uses Linux ftrace.
.SH SYNOPSIS
.B opensnoop
[\-htx] [\-d secs] [\-p pid] [\-n name] [filename]
[\-htx] [\-d secs] [\-p pid] [\-L tid] [\-n name] [filename]
.SH DESCRIPTION
This traces open() syscalls, showing the file name (pathname) and returned file
descriptor number (or \-1, for error).
@@ -41,6 +41,9 @@ expressions are allowed. This is post-filtered using awk.
\-p PID
Only trace this process ID. This is filtered in-kernel.
.TP
\-L TID
Only trace this thread ID. This is filtered in-kernel.
.TP
\-t
Include timestamps, in seconds.
.TP

View File

@@ -3,7 +3,7 @@
tpoint \- trace a given tracepoint. Static tracing. Uses Linux ftrace.
.SH SYNOPSIS
.B tpoint
[\-hHsv] [\-d secs] [\-p PID] tracepoint [filter]
[\-hHsv] [\-d secs] [\-p PID] [\-L TID] tracepoint [filter]
.B tpoint
\-l
@@ -53,6 +53,9 @@ for use in a custom filter.
\-p PID
Only trace kernel functions when this process ID is on-CPU.
.TP
\-L TID
Only trace kernel functions when this thread ID is on-CPU.
.TP
tracepoint
A tracepoint name. Eg, block:block_rq_issue. See the EXAMPLES section.
.TP

View File

@@ -3,7 +3,7 @@
uprobe \- trace a given uprobe definition. User-level dynamic tracing. Uses Linux ftrace. EXPERIMENTAL.
.SH SYNOPSIS
.B uprobe
[\-FhHsv] [\-d secs] [\-p PID] {\-l target | uprobe_definition [filter]}
[\-FhHsv] [\-d secs] [\-p PID] [\-L TID] {\-l target | uprobe_definition [filter]}
.SH DESCRIPTION
This will create, trace, then destroy a given uprobe definition. See
Documentation/trace/uprobetracer.txt in the Linux kernel source for the
@@ -70,6 +70,9 @@ for use in a custom filter.
\-p PID
Only trace user-level functions when this process ID is on-CPU.
.TP
\-L TID
Only trace user-level functions when this thread ID is on-CPU.
.TP
uprobe_definition
A full uprobe definition, as documented by Documentation/trace/uprobetracer.txt
in the Linux kernel source. Note that the probe alias name is optional with

View File

@@ -13,7 +13,7 @@
# It is a workaround, and proof of concept for ftrace, until more kernel tracing
# functionality is available.
#
# USAGE: ./opensnoop [-htx] [-d secs] [-p pid] [-n name] [filename]
# USAGE: ./opensnoop [-htx] [-d secs] [-p pid] [-L tid] [-n name] [filename]
#
# Run "opensnoop -h" for full usage.
#
@@ -48,16 +48,17 @@
### default variables
tracing=/sys/kernel/debug/tracing
flock=/var/tmp/.ftrace-lock; wroteflock=0
opt_duration=0; duration=; opt_name=0; name=; opt_pid=0; pid=; ftext=
opt_time=0; opt_fail=0; opt_file=0; file=
opt_duration=0; duration=; opt_name=0; name=; opt_pid=0; pid=; opt_tid=0; tid=
ftext=; opt_time=0; opt_fail=0; opt_file=0; file=
trap ':' INT QUIT TERM PIPE HUP # sends execution to end tracing section
function usage {
cat <<-END >&2
USAGE: opensnoop [-htx] [-d secs] [-p PID] [-n name] [filename]
USAGE: opensnoop [-htx] [-d secs] [-p PID] [-L TID] [-n name] [filename]
-d seconds # trace duration, and use buffers
-n name # process name to match on I/O issue
-p PID # PID to match on I/O issue
-n name # process name to match on open
-p PID # PID to match on open
-L TID # PID to match on open
-t # include time (seconds)
-x # only show failed opens
-h # this usage message
@@ -87,7 +88,7 @@ function end {
cd $tracing
warn "echo 0 > events/kprobes/getnameprobe/enable"
warn "echo 0 > events/syscalls/sys_exit_open/enable"
if (( opt_pid )); then
if (( opt_pid || opt_tid )); then
warn "echo 0 > events/kprobes/getnameprobe/filter"
warn "echo 0 > events/syscalls/sys_exit_open/filter"
fi
@@ -110,12 +111,13 @@ function edie {
}
### process options
while getopts d:hn:p:tx opt
while getopts d:hn:p:L:tx opt
do
case $opt in
d) opt_duration=1; duration=$OPTARG ;;
n) opt_name=1; name=$OPTARG ;;
p) opt_pid=1; pid=$OPTARG ;;
L) opt_tid=1; tid=$OPTARG ;;
t) opt_time=1 ;;
x) opt_fail=1 ;;
h|?) usage ;;
@@ -130,8 +132,10 @@ fi
(( $# )) && usage
### option logic
(( opt_pid && opt_name )) && die "ERROR: use either -p or -n."
(( opt_pid + opt_name + opt_tid > 1 )) && \
die "ERROR: use at most one of -p, -n, -L."
(( opt_pid )) && ftext=" issued by PID $pid"
(( opt_tid )) && ftext=" issued by TID $tid"
(( opt_name )) && ftext=" issued by process name \"$name\""
(( opt_file )) && ftext="$ftext for filenames containing \"$file\""
if (( opt_duration )); then
@@ -167,12 +171,24 @@ if ! echo $kprobe >> kprobe_events; then
edie "ERROR: adding a kprobe for getname(). Exiting."
fi
if (( opt_pid )); then
if ! echo "common_pid==$pid" > events/kprobes/getnameprobe/filter || \
! echo "common_pid==$pid" > events/syscalls/sys_exit_open/filter
filter=
for tid in /proc/$pid/task/*; do
filter="$filter || common_pid == ${tid##*/}"
done
filter=${filter:3} # trim leading ' || ' (four characters)
if ! echo $filter > events/kprobes/getnameprobe/filter || \
! echo $filter > events/syscalls/sys_exit_open/filter
then
edie "ERROR: setting -p $pid. Exiting."
fi
fi
if (( opt_tid )); then
if ! echo "common_pid == $tid" > events/kprobes/getnameprobe/filter || \
! echo "common_pid == $tid" > events/syscalls/sys_exit_open/filter
then
edie "ERROR: setting -L $tid. Exiting."
fi
fi
if ! echo 1 > events/kprobes/getnameprobe/enable; then
edie "ERROR: enabling kprobe for getname(). Exiting."
fi

View File

@@ -8,7 +8,7 @@
# printing live tracepoint events only. Wildcards are currently not supported.
# If this is insufficient for any reason, use the perf command instead.
#
# USAGE: ./tpoint [-hHsv] [-d secs] [-p pid] tracepoint [filter]
# USAGE: ./tpoint [-hHsv] [-d secs] [-p pid] [-L tid] tracepoint [filter]
# ./tpoint -l
#
# Run "tpoint -h" for full usage.
@@ -53,16 +53,17 @@
### default variables
tracing=/sys/kernel/debug/tracing
flock=/var/tmp/.ftrace-lock; wroteflock=0
opt_duration=0; duration=; opt_pid=0; pid=; opt_filter=0; filter=
opt_view=0; opt_headers=0; opt_stack=0; dmesg=2
opt_duration=0; duration=; opt_pid=0; pid=; opt_tid=0; tid=
opt_filter=0; filter=; opt_view=0; opt_headers=0; opt_stack=0; dmesg=2
trap ':' INT QUIT TERM PIPE HUP # sends execution to end tracing section
function usage {
cat <<-END >&2
USAGE: tpoint [-hHsv] [-d secs] [-p PID] tracepoint [filter]
USAGE: tpoint [-hHsv] [-d secs] [-p PID] [-L TID] tracepoint [filter]
tpoint -l
-d seconds # trace duration, and use buffers
-p PID # PID to match on I/O issue
-p PID # PID to match on event
-L TID # thread id to match on event
-v # view format file (don't trace)
-H # include column headers
-l # list all tracepoints
@@ -117,11 +118,12 @@ function edie {
}
### process options
while getopts d:hHlp:sv opt
while getopts d:hHlp:L:sv opt
do
case $opt in
d) opt_duration=1; duration=$OPTARG ;;
p) opt_pid=1; pid=$OPTARG ;;
L) opt_tid=1; tid=$OPTARG ;;
H) opt_headers=1 ;;
l) opt_list=1 ;;
s) opt_stack=1 ;;
@@ -141,12 +143,21 @@ if (( !opt_list )); then
fi
### option logic
(( opt_pid && opt_filter )) && die "ERROR: use either -p or -f."
(( opt_pid + opt_filter + opt_tid > 1 )) && \
die "ERROR: use at most one of -p, -L, or filter."
(( opt_duration && opt_view )) && die "ERROR: use either -d or -v."
if (( opt_pid )); then
# convert to filter
opt_filter=1
filter="common_pid == $pid"
# ftrace common_pid is thread id from user's perspective
for tid in /proc/$pid/task/*; do
filter="$filter || common_pid == ${tid##*/}"
done
filter=${filter:3} # trim leading ' || ' (four characters)
fi
if (( opt_tid )); then
opt_filter=1
filter="common_pid == $tid"
fi
if (( !opt_view && !opt_list )); then
if (( opt_duration )); then

View File

@@ -8,7 +8,7 @@
# syntax of a uprobe definition, and "uprobe -h" for examples. With this tool,
# the probe alias is optional (it will default to something meaningful).
#
# USAGE: ./uprobe [-FhHsv] [-d secs] [-p pid] {-l target |
# USAGE: ./uprobe [-FhHsv] [-d secs] [-p pid] [-L tid] {-l target |
# uprobe_definition [filter]}
#
# Run "uprobe -h" for full usage.
@@ -63,20 +63,21 @@
### default variables
tracing=/sys/kernel/debug/tracing
flock=/var/tmp/.ftrace-lock; wroteflock=0
opt_duration=0; duration=; opt_pid=0; pid=; opt_filter=0; filter=
opt_view=0; opt_headers=0; opt_stack=0; dmesg=2; debug=0; opt_force=0
opt_list=0; target=
opt_duration=0; duration=; opt_pid=0; pid=; opt_tid=0; tid=
opt_filter=0; filter=; opt_view=0; opt_headers=0; opt_stack=0; dmesg=2
debug=0; opt_force=0; opt_list=0; target=
PATH=$PATH:/usr/bin:/sbin # ensure we find objdump, ldconfig
trap ':' INT QUIT TERM PIPE HUP # sends execution to end tracing section
function usage {
cat <<-END >&2
USAGE: uprobe [-FhHsv] [-d secs] [-p PID] {-l target |
USAGE: uprobe [-FhHsv] [-d secs] [-p PID] [-L TID] {-l target |
uprobe_definition [filter]}
-F # force. trace despite warnings.
-d seconds # trace duration, and use buffers
-l target # list functions from this executable
-p PID # PID to match on events
-L TID # thread id to match on events
-v # view format file (don't trace)
-H # include column headers
-s # show user stack traces
@@ -192,12 +193,13 @@ function set_addr {
}
### process options
while getopts Fd:hHl:p:sv opt
while getopts Fd:hHl:p:L:sv opt
do
case $opt in
F) opt_force=1 ;;
d) opt_duration=1; duration=$OPTARG ;;
p) opt_pid=1; pid=$OPTARG ;;
L) opt_tid=1; tid=$OPTARG ;;
l) opt_list=1; target=$OPTARG ;;
H) opt_headers=1 ;;
s) opt_stack=1 ;;
@@ -248,12 +250,21 @@ done
### option logic
[[ "$uprobe" == "" ]] && usage
(( opt_pid && opt_filter )) && die "ERROR: use either -p or a filter."
(( opt_pid + opt_filter + opt_tid > 1 )) && \
die "ERROR: use at most one of -p, -L, or filter."
(( opt_duration && opt_view )) && die "ERROR: use either -d or -v."
if (( opt_pid )); then
# convert to filter
opt_filter=1
filter="common_pid == $pid"
# ftrace common_pid is thread id from user's perspective
for tid in /proc/$pid/task/*; do
filter="$filter || common_pid == ${tid##*/}"
done
filter=${filter:3} # trim leading ' || ' (four characters)
fi
if (( opt_tid )); then
opt_filter=1
filter="common_pid == $tid"
fi
if [[ "$uprobe" != p:* && "$uprobe" != r:* ]]; then
echo >&2 "ERROR: invalid uprobe definition (should start with p: or r:)"