aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/tracing
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2016-09-21 13:43:48 -0400
committerSteven Rostedt <rostedt@goodmis.org>2016-09-21 13:56:55 -0400
commit951dbf500aa7df051d7cde15b9ac05608c0bb16f (patch)
tree36cefe0aa1b559a7a41ac1c19a418ef636324201 /scripts/tracing
parentf971cc9aabc287120bbe7f3f1abe70c13e61ee94 (diff)
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>
Diffstat (limited to 'scripts/tracing')
-rwxr-xr-xscripts/tracing/ftrace-bisect.sh115
1 files changed, 115 insertions, 0 deletions
diff --git a/scripts/tracing/ftrace-bisect.sh b/scripts/tracing/ftrace-bisect.sh
new file mode 100755
index 000000000000..9ff8ac5fc53c
--- /dev/null
+++ b/scripts/tracing/ftrace-bisect.sh
@@ -0,0 +1,115 @@
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
74if [ $# -ne 3 ]; then
75 echo 'usage: ftrace-bisect full-file test-file non-test-file'
76 exit
77fi
78
79full=$1
80test=$2
81nontest=$3
82
83x=`cat $full | wc -l`
84if [ $x -eq 1 ]; then
85 echo "There's only one function left, must be the bad one"
86 cat $full
87 exit 0
88fi
89
90let x=$x/2
91let y=$x+1
92
93if [ ! -f $full ]; then
94 echo "$full does not exist"
95 exit 1
96fi
97
98if [ -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
104fi
105
106if [ -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
112fi
113
114sed -ne "1,${x}p" $full > $test
115sed -ne "$y,\$p" $full > $nontest