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