Files
perf-tools/kernel/functrace

130 lines
4.0 KiB
Plaintext
Raw Normal View History

2014-07-13 10:37:44 -07:00
#!/bin/bash
#
# functrace - trace kernel function calls matching specified wildcards.
# A hack using Linux ftrace.
#
# This is a proof of concept using Linux ftrace capabilities circa Linux 3.2.
#
# USAGE: functrace [-h] [-d secs] funcstring
# eg,
# functrace '*sleep' # trace all functions ending in "sleep"
#
# Run "functrace -h" for full usage.
#
# The output format is the same as the ftrace function trace format, described
# in the kernel source under Documentation/trace/ftrace.txt.
#
# The "-d duration" mode leaves the trace data in the kernel buffer, and
# only reads it at the end. If the trace data is large, beware of exhausting
# buffer space (/sys/kernel/debug/tracing/buffer_size_kb) and losing data.
#
# Also beware of feedback loops: tracing tcp* functions over an ssh session,
# or writing ext4* functions to an ext4 file system. For the former, tcp
# trace data could be redirected to a file (as in the usage message). For
# the latter, trace to the screen or a different file system.
#
# WARNING: This uses dynamic tracing of kernel functions, and could cause
# kernel panics or freezes. Test, and know what you are doing, before use.
#
# OVERHEADS: This can generate a lot of trace data quickly, depending on the
# frequency of the traced events. Such data will cause performance overheads.
#
# From perf-tools: https://github.com/brendangregg/perf-tools
#
# 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)
#
# 12-Jul-2014 Brendan Gregg Created this.
# default variables
tracing=/sys/kernel/debug/tracing
opt_duration=0; duration=
trap ':' SIGINT
function usage {
cat <<-END >&2
USAGE: functrace [-h] [-d secs] funcstring
-d seconds # total duration of trace; this mode
# buffers tracing for this duration
-h # this usage message
eg,
functrace do_nanosleep # trace the do_nanosleep() function
functrace '*sleep' # trace functions ending in "sleep"
functrace 'tcp*' > out # trace all "tcp*" funcs to out file
functrace -d 1 'tcp*' > out # trace 1 sec, then write out file
END
exit
}
function warn {
if ! eval "$@"; then
echo "WARNING: command failed \"$@\""
fi
}
# process options
while getopts d:h name
do
case $name in
d) opt_duration=1; duration=$OPTARG ;;
h|?) usage ;;
esac
done
shift $(( $OPTIND - 1 ))
# option logic
(( $# == 0 )) && usage
funcs="$1"
if (( opt_duration )); then
echo "Tracing \"$funcs\" for $duration seconds..."
else
echo "Tracing \"$funcs\"... Ctrl-C to end."
fi
# setup and commence tracing
if [[ ! -x $tracing ]]; then
echo "ERROR: accessing tracing. Root user? Kernel has FTRACE? Exiting."
exit 1
fi
sysctl -q kernel.ftrace_enabled=1 # doesn't set exit status
if ! echo "$funcs" > $tracing/set_ftrace_filter; then
echo "ERROR: enabling \"$funcs\". Exiting."
exit 1
fi
if ! echo function > $tracing/current_tracer; then
echo "ERROR: setting current_tracer to \"function\". Exiting."
exit 1
fi
# print trace buffer
end=0; secs=0
warn "echo > $tracing/trace"
if (( opt_duration )); then
sleep $duration
cat $tracing/trace
else
cat $tracing/trace_pipe
fi
# end tracing
echo
echo "Ending tracing..."
warn "echo nop > $tracing/current_tracer"
warn "echo > $tracing/set_ftrace_filter"
warn "echo > $tracing/trace"