xref: /linux/tools/perf/tests/shell/base_probe/test_adding_kernel.sh (revision e3966940559d52aa1800a008dcfeec218dd31f88)
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