diff --git a/examples/functrace_example.txt b/examples/functrace_example.txt index 5a2f9b9..6db51a4 100644 --- a/examples/functrace_example.txt +++ b/examples/functrace_example.txt @@ -325,11 +325,12 @@ and events were missed. Use -h to print the USAGE message: # ./functrace -h -USAGE: functrace [-hH] [-p PID] [-d secs] funcstring +USAGE: functrace [-hH] [-p PID] [-L TID] [-d secs] funcstring -d seconds # trace duration, and use buffers -h # this usage message -H # include column headers -p PID # trace when this pid is on-CPU + -L TID # trace when this thread is on-CPU eg, functrace do_nanosleep # trace the do_nanosleep() function functrace '*sleep' # trace functions ending in "sleep" diff --git a/kernel/functrace b/kernel/functrace index 3abf4a0..0736392 100755 --- a/kernel/functrace +++ b/kernel/functrace @@ -5,7 +5,7 @@ # # This is a proof of concept using Linux ftrace capabilities on older kernels. # -# USAGE: functrace [-hH] [-p PID] [-d secs] funcstring +# USAGE: functrace [-hH] [-p PID] [-L TID] [-d secs] funcstring # eg, # functrace '*sleep' # trace all functions ending in "sleep" # @@ -59,16 +59,18 @@ ### default variables tracing=/sys/kernel/debug/tracing flock=/var/tmp/.ftrace-lock -opt_duration=0; duration=; opt_pid=0; pid=; pidtext=; opt_headers=0 +opt_duration=0; duration=; opt_pid=0; pid=; opt_tid=0; tid=; pidtext= +opt_headers=0 trap ':' INT QUIT TERM PIPE HUP # sends execution to end tracing section function usage { cat <<-END >&2 - USAGE: functrace [-hH] [-p PID] [-d secs] funcstring + USAGE: functrace [-hH] [-p PID] [-L TID] [-d secs] funcstring -d seconds # trace duration, and use buffers -h # this usage message -H # include column headers -p PID # trace when this pid is on-CPU + -L TID # trace when this thread is on-CPU eg, functrace do_nanosleep # trace the do_nanosleep() function functrace '*sleep' # trace functions ending in "sleep" @@ -93,7 +95,7 @@ function end { echo "Ending tracing..." 2>/dev/null cd $tracing warn "echo nop > current_tracer" - (( opt_pid )) && warn "echo > set_ftrace_pid" + (( opt_pid || opt_tid )) && warn "echo > set_ftrace_pid" warn "echo > set_ftrace_filter" warn "echo > trace" (( wroteflock )) && warn "rm $flock" @@ -113,11 +115,12 @@ function edie { } ### process options -while getopts d:hHp: opt +while getopts d:hHp:L: 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; ;; h|?) usage ;; esac @@ -126,8 +129,10 @@ shift $(( $OPTIND - 1 )) ### option logic (( $# == 0 )) && usage +(( opt_pid && opt_tid )) && edie "ERROR: You can use -p or -L but not both." funcs="$1" (( opt_pid )) && pidtext=" for PID $pid" +(( opt_tid )) && pidtext=" for TID $pid" if (( opt_duration )); then echo "Tracing \"$funcs\"$pidtext for $duration seconds..." else @@ -148,9 +153,18 @@ sysctl -q kernel.ftrace_enabled=1 # doesn't set exit status read mode < current_tracer [[ "$mode" != "nop" ]] && edie "ERROR: ftrace active (current_tracer=$mode)" if (( opt_pid )); then - if ! echo $pid > set_ftrace_pid; then - edie "ERROR: setting -p $pid (PID exist?). Exiting." - fi + echo > set_ftrace_pid + # ftrace expects kernel pids, which are thread ids + for tid in /proc/$pid/task/*; do + if ! echo ${tid##*/} >> set_ftrace_pid; then + edie "ERROR: setting -p $pid (PID exist?). Exiting." + fi + done +fi +if (( opt_tid )); then + if ! echo $tid > set_ftrace_pid; then + edie "ERROR: setting -L $tid (TID exist?). Exiting." + fi fi if ! echo "$funcs" > set_ftrace_filter; then edie "ERROR: enabling \"$funcs\". Exiting." diff --git a/man/man8/functrace.8 b/man/man8/functrace.8 index a9b9904..bd7f08c 100644 --- a/man/man8/functrace.8 +++ b/man/man8/functrace.8 @@ -3,7 +3,7 @@ functrace \- trace kernel function calls matching specified wildcards. Uses Linux ftrace. .SH SYNOPSIS .B functrace -[\-hH] [\-p PID] [\-d secs] funcstring +[\-hH] [\-p PID] [\-L TID] [\-d secs] funcstring .SH DESCRIPTION This tool provides a quick way to capture the execution of kernel functions, showing basic details including as the process ID, timestamp, and calling @@ -45,6 +45,9 @@ Print column headers. \-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 funcstring A function name to trace, which may include file glob style wildcards ("*") at the beginning or ending of a string only. Eg, "vfs*" means match "vfs" followed