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