linux/scripts/tracing/ftrace-bisect.sh
<<
>>
Prefs
   1#!/bin/bash
   2# SPDX-License-Identifier: GPL-2.0
   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
  75if [ $# -ne 3 ]; then
  76  echo 'usage: ftrace-bisect full-file test-file  non-test-file'
  77  exit
  78fi
  79
  80full=$1
  81test=$2
  82nontest=$3
  83
  84x=`cat $full | wc -l`
  85if [ $x -eq 1 ]; then
  86        echo "There's only one function left, must be the bad one"
  87        cat $full
  88        exit 0
  89fi
  90
  91let x=$x/2
  92let y=$x+1
  93
  94if [ ! -f $full ]; then
  95        echo "$full does not exist"
  96        exit 1
  97fi
  98
  99if [ -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
 105fi
 106
 107if [ -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
 113fi
 114
 115sed -ne "1,${x}p" $full > $test
 116sed -ne "$y,\$p" $full > $nontest
 117