1#!/bin/bash 2# Add 'perf probe's, list and remove them 3# SPDX-License-Identifier: GPL-2.0 4 5# 6# test_adding_kernel of perf_probe test 7# Author: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> 8# Author: Michael Petlan <mpetlan@redhat.com> 9# 10# Description: 11# 12# This test tests adding of probes, their correct listing 13# and removing. 14# 15 16# include working environment 17. ../common/init.sh 18. ./settings.sh 19 20# shellcheck disable=SC2034 # the variable is later used after the working environment is included 21THIS_TEST_NAME=`basename $0 .sh` 22TEST_RESULT=0 23 24# shellcheck source=lib/probe_vfs_getname.sh 25. "$(dirname "$0")/../lib/probe_vfs_getname.sh" 26 27TEST_PROBE=${TEST_PROBE:-"inode_permission"} 28 29# set NO_DEBUGINFO to skip testcase if debuginfo is not present 30# skip_if_no_debuginfo returns 2 if debuginfo is not present 31skip_if_no_debuginfo 32if [ $? -eq 2 ]; then 33 NO_DEBUGINFO=1 34fi 35 36check_kprobes_available 37if [ $? -ne 0 ]; then 38 print_overall_skipped 39 exit 0 40fi 41 42 43### basic probe adding 44 45for opt in "" "-a" "--add"; do 46 clear_all_probes 47 $CMD_PERF probe $opt $TEST_PROBE 2> $LOGS_DIR/adding_kernel_add$opt.err 48 PERF_EXIT_CODE=$? 49 50 ../common/check_all_patterns_found.pl "Added new events?:" "probe:$TEST_PROBE" "on $TEST_PROBE" < $LOGS_DIR/adding_kernel_add$opt.err 51 CHECK_EXIT_CODE=$? 52 53 print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "adding probe $TEST_PROBE :: $opt" 54 (( TEST_RESULT += $? )) 55done 56 57 58### listing added probe :: perf list 59 60# any added probes should appear in perf-list output 61$CMD_PERF list probe:\* > $LOGS_DIR/adding_kernel_list.log 62PERF_EXIT_CODE=$? 63 64../common/check_all_lines_matched.pl "$RE_LINE_EMPTY" "List of pre-defined events" "probe:${TEST_PROBE}(?:_\d+)?\s+\[Tracepoint event\]" "Metric Groups:" < $LOGS_DIR/adding_kernel_list.log 65CHECK_EXIT_CODE=$? 66 67print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "listing added probe :: perf list" 68(( TEST_RESULT += $? )) 69 70 71### listing added probe :: perf probe -l 72 73# '-l' should list all the added probes as well 74$CMD_PERF probe -l > $LOGS_DIR/adding_kernel_list-l.log 75PERF_EXIT_CODE=$? 76 77../common/check_all_patterns_found.pl "\s*probe:${TEST_PROBE}(?:_\d+)?\s+\(on ${TEST_PROBE}(?:[:\+]$RE_NUMBER_HEX)?@.+\)" < $LOGS_DIR/adding_kernel_list-l.log 78CHECK_EXIT_CODE=$? 79 80if [ $NO_DEBUGINFO ] ; then 81 print_testcase_skipped $NO_DEBUGINFO $NO_DEBUGINFO "Skipped due to missing debuginfo" 82else 83 print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "listing added probe :: perf probe -l" 84fi 85 86(( TEST_RESULT += $? )) 87 88 89### using added probe 90 91$CMD_PERF stat -e probe:$TEST_PROBE\* -o $LOGS_DIR/adding_kernel_using_probe.log -- cat /proc/uptime > /dev/null 92PERF_EXIT_CODE=$? 93 94REGEX_STAT_HEADER="\s*Performance counter stats for \'cat /proc/uptime\':" 95REGEX_STAT_VALUES="\s*\d+\s+probe:$TEST_PROBE" 96# the value should be greater than 1 97REGEX_STAT_VALUE_NONZERO="\s*[1-9][0-9]*\s+probe:$TEST_PROBE" 98REGEX_STAT_TIME="\s*$RE_NUMBER\s+seconds (?:time elapsed|user|sys)" 99../common/check_all_lines_matched.pl "$REGEX_STAT_HEADER" "$REGEX_STAT_VALUES" "$REGEX_STAT_TIME" "$RE_LINE_COMMENT" "$RE_LINE_EMPTY" < $LOGS_DIR/adding_kernel_using_probe.log 100CHECK_EXIT_CODE=$? 101../common/check_all_patterns_found.pl "$REGEX_STAT_HEADER" "$REGEX_STAT_VALUE_NONZERO" "$REGEX_STAT_TIME" < $LOGS_DIR/adding_kernel_using_probe.log 102(( CHECK_EXIT_CODE += $? )) 103 104print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "using added probe" 105(( TEST_RESULT += $? )) 106 107 108### removing added probe 109 110# '-d' should remove the probe 111$CMD_PERF probe -d $TEST_PROBE\* 2> $LOGS_DIR/adding_kernel_removing.err 112PERF_EXIT_CODE=$? 113 114../common/check_all_lines_matched.pl "Removed event: probe:$TEST_PROBE" < $LOGS_DIR/adding_kernel_removing.err 115CHECK_EXIT_CODE=$? 116 117print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "deleting added probe" 118(( TEST_RESULT += $? )) 119 120 121### listing removed probe 122 123# removed probes should NOT appear in perf-list output 124$CMD_PERF list probe:\* > $LOGS_DIR/adding_kernel_list_removed.log 125PERF_EXIT_CODE=$? 126 127../common/check_all_lines_matched.pl "$RE_LINE_EMPTY" "List of pre-defined events" "Metric Groups:" < $LOGS_DIR/adding_kernel_list_removed.log 128CHECK_EXIT_CODE=$? 129 130print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "listing removed probe (should NOT be listed)" 131(( TEST_RESULT += $? )) 132 133 134### dry run 135 136# the '-n' switch should run it in dry mode 137$CMD_PERF probe -n --add $TEST_PROBE 2> $LOGS_DIR/adding_kernel_dryrun.err 138PERF_EXIT_CODE=$? 139 140# check for the output (should be the same as usual) 141../common/check_all_patterns_found.pl "Added new events?:" "probe:$TEST_PROBE" "on $TEST_PROBE" < $LOGS_DIR/adding_kernel_dryrun.err 142CHECK_EXIT_CODE=$? 143 144# check that no probe was added in real 145! ( $CMD_PERF probe -l | grep "probe:$TEST_PROBE" ) 146(( CHECK_EXIT_CODE += $? )) 147 148print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "dry run :: adding probe" 149(( TEST_RESULT += $? )) 150 151 152### force-adding probes 153 154# when using '--force' a probe should be added even if it is already there 155$CMD_PERF probe --add $TEST_PROBE 2> $LOGS_DIR/adding_kernel_forceadd_01.err 156PERF_EXIT_CODE=$? 157 158../common/check_all_patterns_found.pl "Added new events?:" "probe:$TEST_PROBE" "on $TEST_PROBE" < $LOGS_DIR/adding_kernel_forceadd_01.err 159CHECK_EXIT_CODE=$? 160 161print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "force-adding probes :: first probe adding" 162(( TEST_RESULT += $? )) 163 164# adding existing probe without '--force' should fail 165! $CMD_PERF probe --add $TEST_PROBE 2> $LOGS_DIR/adding_kernel_forceadd_02.err 166PERF_EXIT_CODE=$? 167 168../common/check_all_patterns_found.pl "Error: event \"$TEST_PROBE\" already exists." "Error: Failed to add events." < $LOGS_DIR/adding_kernel_forceadd_02.err 169CHECK_EXIT_CODE=$? 170 171print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "force-adding probes :: second probe adding (without force)" 172(( TEST_RESULT += $? )) 173 174# adding existing probe with '--force' should pass 175NO_OF_PROBES=`$CMD_PERF probe -l | wc -l` 176$CMD_PERF probe --force --add $TEST_PROBE 2> $LOGS_DIR/adding_kernel_forceadd_03.err 177PERF_EXIT_CODE=$? 178 179../common/check_all_patterns_found.pl "Added new events?:" "probe:${TEST_PROBE}_${NO_OF_PROBES}" "on $TEST_PROBE" < $LOGS_DIR/adding_kernel_forceadd_03.err 180CHECK_EXIT_CODE=$? 181 182print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "force-adding probes :: second probe adding (with force)" 183(( TEST_RESULT += $? )) 184 185 186### using doubled probe 187 188# since they are the same, they should produce the same results 189$CMD_PERF stat -e probe:$TEST_PROBE -e probe:${TEST_PROBE}_${NO_OF_PROBES} -x';' -o $LOGS_DIR/adding_kernel_using_two.log -- bash -c 'cat /proc/cpuinfo > /dev/null' 190PERF_EXIT_CODE=$? 191 192REGEX_LINE="$RE_NUMBER;+probe:${TEST_PROBE}_?(?:$NO_OF_PROBES)?;$RE_NUMBER;$RE_NUMBER" 193../common/check_all_lines_matched.pl "$REGEX_LINE" "$RE_LINE_EMPTY" "$RE_LINE_COMMENT" < $LOGS_DIR/adding_kernel_using_two.log 194CHECK_EXIT_CODE=$? 195 196VALUE_1=`grep "$TEST_PROBE;" $LOGS_DIR/adding_kernel_using_two.log | awk -F';' '{print $1}'` 197VALUE_2=`grep "${TEST_PROBE}_${NO_OF_PROBES};" $LOGS_DIR/adding_kernel_using_two.log | awk -F';' '{print $1}'` 198 199test $VALUE_1 -eq $VALUE_2 200(( CHECK_EXIT_CODE += $? )) 201 202print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "using doubled probe" 203 204 205### removing multiple probes 206 207# using wildcards should remove all matching probes 208$CMD_PERF probe --del \* 2> $LOGS_DIR/adding_kernel_removing_wildcard.err 209PERF_EXIT_CODE=$? 210 211../common/check_all_lines_matched.pl "Removed event: probe:$TEST_PROBE" "Removed event: probe:${TEST_PROBE}_1" < $LOGS_DIR/adding_kernel_removing_wildcard.err 212CHECK_EXIT_CODE=$? 213 214print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "removing multiple probes" 215(( TEST_RESULT += $? )) 216 217 218### wildcard adding support 219 220$CMD_PERF probe -nf --max-probes=512 -a 'vfs_* $params' 2> $LOGS_DIR/adding_kernel_adding_wildcard.err 221PERF_EXIT_CODE=$? 222 223../common/check_all_patterns_found.pl "probe:vfs_mknod" "probe:vfs_create" "probe:vfs_rmdir" "probe:vfs_link" "probe:vfs_write" < $LOGS_DIR/adding_kernel_adding_wildcard.err 224CHECK_EXIT_CODE=$? 225 226if [ $NO_DEBUGINFO ] ; then 227 print_testcase_skipped $NO_DEBUGINFO $NO_DEBUGINFO "Skipped due to missing debuginfo" 228else 229 print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "wildcard adding support" 230fi 231 232(( TEST_RESULT += $? )) 233 234 235### non-existing variable 236 237# perf probe should survive a non-existing variable probing attempt 238{ $CMD_PERF probe 'vfs_read somenonexistingrandomstuffwhichisalsoprettylongorevenlongertoexceed64' ; } 2> $LOGS_DIR/adding_kernel_nonexisting.err 239PERF_EXIT_CODE=$? 240 241# the exitcode should not be 0 or segfault 242test $PERF_EXIT_CODE -ne 139 -a $PERF_EXIT_CODE -ne 0 243PERF_EXIT_CODE=$? 244 245# check that the error message is reasonable 246../common/check_all_patterns_found.pl "Failed to find" "somenonexistingrandomstuffwhichisalsoprettylongorevenlongertoexceed64" < $LOGS_DIR/adding_kernel_nonexisting.err 247CHECK_EXIT_CODE=$? 248../common/check_all_patterns_found.pl "in this function|at this address" "Error" "Failed to add events" < $LOGS_DIR/adding_kernel_nonexisting.err 249(( CHECK_EXIT_CODE += $? )) 250../common/check_all_lines_matched.pl "Failed to find" "Error" "Probe point .+ not found" "optimized out" "Use.+\-\-range option to show.+location range" < $LOGS_DIR/adding_kernel_nonexisting.err 251(( CHECK_EXIT_CODE += $? )) 252../common/check_no_patterns_found.pl "$RE_SEGFAULT" < $LOGS_DIR/adding_kernel_nonexisting.err 253(( CHECK_EXIT_CODE += $? )) 254 255if [ $NO_DEBUGINFO ]; then 256 print_testcase_skipped $NO_DEBUGINFO $NO_DEBUGINFO "Skipped due to missing debuginfo" 257else 258 print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "non-existing variable" 259fi 260 261(( TEST_RESULT += $? )) 262 263 264### function with return value 265 266# adding probe with return value 267$CMD_PERF probe --add "$TEST_PROBE%return \$retval" 2> $LOGS_DIR/adding_kernel_func_retval_add.err 268PERF_EXIT_CODE=$? 269 270../common/check_all_patterns_found.pl "Added new events?:" "probe:$TEST_PROBE" "on $TEST_PROBE%return with \\\$retval" < $LOGS_DIR/adding_kernel_func_retval_add.err 271CHECK_EXIT_CODE=$? 272 273print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "function with retval :: add" 274(( TEST_RESULT += $? )) 275 276# recording some data 277$CMD_PERF record -e probe:$TEST_PROBE\* -o $CURRENT_TEST_DIR/perf.data -- cat /proc/cpuinfo > /dev/null 2> $LOGS_DIR/adding_kernel_func_retval_record.err 278PERF_EXIT_CODE=$? 279 280../common/check_all_patterns_found.pl "$RE_LINE_RECORD1" "$RE_LINE_RECORD2" < $LOGS_DIR/adding_kernel_func_retval_record.err 281CHECK_EXIT_CODE=$? 282 283print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "function with retval :: record" 284(( TEST_RESULT += $? )) 285 286# perf script should report the function calls with the correct arg values 287$CMD_PERF script -i $CURRENT_TEST_DIR/perf.data > $LOGS_DIR/adding_kernel_func_retval_script.log 288PERF_EXIT_CODE=$? 289 290REGEX_SCRIPT_LINE="\s*cat\s+$RE_NUMBER\s+\[$RE_NUMBER\]\s+$RE_NUMBER:\s+probe:$TEST_PROBE\w*:\s+\($RE_NUMBER_HEX\s+<\-\s+$RE_NUMBER_HEX\)\s+arg1=$RE_NUMBER_HEX" 291../common/check_all_lines_matched.pl "$REGEX_SCRIPT_LINE" < $LOGS_DIR/adding_kernel_func_retval_script.log 292CHECK_EXIT_CODE=$? 293../common/check_all_patterns_found.pl "$REGEX_SCRIPT_LINE" < $LOGS_DIR/adding_kernel_func_retval_script.log 294(( CHECK_EXIT_CODE += $? )) 295 296print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "function argument probing :: script" 297(( TEST_RESULT += $? )) 298 299 300clear_all_probes 301 302# print overall results 303print_overall_results "$TEST_RESULT" 304exit $? 305