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