Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ftrace/scripts: Add helper script to bisect function tracing problem functions

Every so often, with a special config or a architecture change, running
function or function_graph tracing can cause the machien to hard reboot,
crash, or simply hard lockup. There's some functions in the function graph
tracer that can not be traced otherwise it causes the function tracer to
recurse before the recursion protection mechanisms are in place.

When this occurs, using the dynamic ftrace featuer that allows limiting what
actually gets traced can be used to bisect down to the problem function.
This adds a script that helps with this process in the scripts/tracing
directory, called ftrace-bisect.sh

The set up is to read all the functions that can be traced from
available_filter_functions into a file (full_file). Then run this script
passing it the full_file and a "test_file" and "non_test_file", where the
test_file will be add to set_ftrace_filter. What ftarce_bisect.sh does, is
to copy half of the functions in full_file into the test_file and the other
half into the non_test_file. This way, one can cat the test_file into the
set_ftrace_filter functions and only test the functions that are in that
file. If it works, then we run the process again after copying non_test_file
to full_file and repeating the process. If the system crashed, then the bad
function is in the test_file and after a reboot, the test_file becomes the
new full_file in the next iteration.

When we get down to a single function in the full_file, then
ftrace_bisect.sh will report that as the bad function.

Full documentation of how to use this simple script is within the script
file itself.

Link: http://lkml.kernel.org/r/20160920100716.131d3647@gandalf.local.home

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>

+115
+115
scripts/tracing/ftrace-bisect.sh
··· 1 + #!/bin/bash 2 + # 3 + # Here's how to use this: 4 + # 5 + # This script is used to help find functions that are being traced by function 6 + # tracer or function graph tracing that causes the machine to reboot, hang, or 7 + # crash. Here's the steps to take. 8 + # 9 + # First, determine if function tracing is working with a single function: 10 + # 11 + # (note, if this is a problem with function_graph tracing, then simply 12 + # replace "function" with "function_graph" in the following steps). 13 + # 14 + # # cd /sys/kernel/debug/tracing 15 + # # echo schedule > set_ftrace_filter 16 + # # echo function > current_tracer 17 + # 18 + # If this works, then we know that something is being traced that shouldn't be. 19 + # 20 + # # echo nop > current_tracer 21 + # 22 + # # cat available_filter_functions > ~/full-file 23 + # # ftrace-bisect ~/full-file ~/test-file ~/non-test-file 24 + # # cat ~/test-file > set_ftrace_filter 25 + # 26 + # *** Note *** this will take several minutes. Setting multiple functions is 27 + # an O(n^2) operation, and we are dealing with thousands of functions. So go 28 + # have coffee, talk with your coworkers, read facebook. And eventually, this 29 + # operation will end. 30 + # 31 + # # echo function > current_tracer 32 + # 33 + # If it crashes, we know that ~/test-file has a bad function. 34 + # 35 + # Reboot back to test kernel. 36 + # 37 + # # cd /sys/kernel/debug/tracing 38 + # # mv ~/test-file ~/full-file 39 + # 40 + # If it didn't crash. 41 + # 42 + # # echo nop > current_tracer 43 + # # mv ~/non-test-file ~/full-file 44 + # 45 + # Get rid of the other test file from previous run (or save them off somewhere). 46 + # # rm -f ~/test-file ~/non-test-file 47 + # 48 + # And start again: 49 + # 50 + # # ftrace-bisect ~/full-file ~/test-file ~/non-test-file 51 + # 52 + # The good thing is, because this cuts the number of functions in ~/test-file 53 + # by half, the cat of it into set_ftrace_filter takes half as long each 54 + # iteration, so don't talk so much at the water cooler the second time. 55 + # 56 + # Eventually, if you did this correctly, you will get down to the problem 57 + # function, and all we need to do is to notrace it. 58 + # 59 + # The way to figure out if the problem function is bad, just do: 60 + # 61 + # # echo <problem-function> > set_ftrace_notrace 62 + # # echo > set_ftrace_filter 63 + # # echo function > current_tracer 64 + # 65 + # And if it doesn't crash, we are done. 66 + # 67 + # If it does crash, do this again (there's more than one problem function) 68 + # but you need to echo the problem function(s) into set_ftrace_notrace before 69 + # enabling function tracing in the above steps. Or if you can compile the 70 + # kernel, annotate the problem functions with "notrace" and start again. 71 + # 72 + 73 + 74 + if [ $# -ne 3 ]; then 75 + echo 'usage: ftrace-bisect full-file test-file non-test-file' 76 + exit 77 + fi 78 + 79 + full=$1 80 + test=$2 81 + nontest=$3 82 + 83 + x=`cat $full | wc -l` 84 + if [ $x -eq 1 ]; then 85 + echo "There's only one function left, must be the bad one" 86 + cat $full 87 + exit 0 88 + fi 89 + 90 + let x=$x/2 91 + let y=$x+1 92 + 93 + if [ ! -f $full ]; then 94 + echo "$full does not exist" 95 + exit 1 96 + fi 97 + 98 + if [ -f $test ]; then 99 + echo -n "$test exists, delete it? [y/N]" 100 + read a 101 + if [ "$a" != "y" -a "$a" != "Y" ]; then 102 + exit 1 103 + fi 104 + fi 105 + 106 + if [ -f $nontest ]; then 107 + echo -n "$nontest exists, delete it? [y/N]" 108 + read a 109 + if [ "$a" != "y" -a "$a" != "Y" ]; then 110 + exit 1 111 + fi 112 + fi 113 + 114 + sed -ne "1,${x}p" $full > $test 115 + sed -ne "$y,\$p" $full > $nontest