diff options
| author | Mark Brown <broonie@kernel.org> | 2026-07-26 22:33:44 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-07-26 22:33:44 +0100 |
| commit | 86625e0f65c9a2b5fee9e0f58cb8a7ebe33b123f (patch) | |
| tree | 8c2f79cdfa36680e79ed80b758669ad70f0d2c09 /tools/testing/selftests | |
| parent | 44cba5a8bd479c33623afada09f2d5b28b846a63 (diff) | |
| parent | 242798675d99ff522fc8720caf68a59ed93fdd6d (diff) | |
| download | linux-next-86625e0f65c9a2b5fee9e0f58cb8a7ebe33b123f.tar.gz linux-next-86625e0f65c9a2b5fee9e0f58cb8a7ebe33b123f.zip | |
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
Diffstat (limited to 'tools/testing/selftests')
8 files changed, 205 insertions, 8 deletions
diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/btf_probe_event.tc b/tools/testing/selftests/ftrace/test.d/dynevent/btf_probe_event.tc new file mode 100644 index 000000000000..bf71368c31a4 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/dynevent/btf_probe_event.tc @@ -0,0 +1,51 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: BTF event with typecast and percpu access +# requires: dynamic_events "this_cpu_read(<fetcharg>)":README "[(structname[,field])]<argname>[->field[->field|.field...]]":README + +# Check if the sample module is loaded +if ! lsmod | grep -q trace_events_sample; then + modprobe trace-events-sample || exit_unresolved +fi + +echo 0 > events/enable +echo > dynamic_events + +# The sample_timer_cb(struct timer_list *t) is called. +# We want to check (STRUCT,FIELD)VAR typecast and this_cpu_read() access. +# (foo_timer_data,timer)t converts t to struct foo_timer_data * using container_of. +# data->counter is a per-cpu pointer to int. +# this_cpu_read(data->counter) should give the value of the counter. + +echo 'f:mysample/myevent sample_timer_cb name=(foo_timer_data,timer)t->name:string count=this_cpu_read((foo_timer_data,timer)t->counter)' >> dynamic_events + +echo 1 > events/mysample/myevent/enable +echo 1 > events/sample-trace/foo_timer_fn/enable + +sleep 2 + +echo 0 > events/mysample/myevent/enable +echo 0 > events/sample-trace/foo_timer_fn/enable + +# Compare the values. +MATCH=0 +while read line; do + if echo $line | grep -q "foo_timer_fn:"; then + NAME=`echo $line | sed 's/.*name=\([^ ]*\) .*/\1/'` + COUNT=`echo $line | sed 's/.*count=\([^ ]*\).*/\1/'` + if grep -q "myevent:.*name=\"${NAME}\" count=$COUNT" trace; then + MATCH=$((MATCH+1)) + fi + fi +done < trace + +if [ $MATCH -eq 0 ]; then + echo "No matching events found" + exit_fail +fi + +# Clean up +echo 0 > events/mysample/myevent/enable +echo 0 > events/sample-trace/foo_timer_fn/enable +echo > dynamic_events +clear_trace diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/btf_typecast_accepted.tc b/tools/testing/selftests/ftrace/test.d/dynevent/btf_typecast_accepted.tc new file mode 100644 index 000000000000..dd5552727054 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/dynevent/btf_typecast_accepted.tc @@ -0,0 +1,103 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: BTF typecast and percpu access syntax validation +# requires: dynamic_events "this_cpu_read(<fetcharg>)":README "[(structname[,field])]<argname>[->field[->field|.field...]]":README + +KPROBES= +FPROBES= + +if grep -qF "p[:[<group>/][<event>]] <place> [<args>]" README ; then + KPROBES=yes +fi +if grep -qF "f[:[<group>/][<event>]] <func-name>[%return] [<args>]" README ; then + FPROBES=yes +fi + +if [ -z "$KPROBES" -a -z "$FPROBES" ] ; then + exit_unsupported +fi + +echo 0 > events/enable +echo > dynamic_events + +# Load trace-events-sample module if available to have per-CPU counter structure defined +if ! lsmod | grep -q trace_events_sample; then + modprobe trace-events-sample || exit_unresolved +fi + +if [ "$FPROBES" ] ; then + # 1. Test basic typecast on fprobe + echo 'f:fpevent1 vfs_read name=(file)file->f_path.dentry->d_name.name:string' >> dynamic_events + # 2. Test parenthesized typecast target on fprobe + echo 'f:fpevent2 vfs_read name=(file)(file)->f_path.dentry->d_name.name:string' >> dynamic_events + # 3. Test nested typecasts on fprobe + echo 'f:fpevent3 vfs_read name=(dentry)((file)file->f_path.dentry)->d_name.name:string' >> dynamic_events + # 4. Test container_of-style typecast with field option on fprobe + echo 'f:fpevent4 vfs_read name=(file,f_path)file->f_mode' >> dynamic_events + # 5. Test typecast on return value on fprobe + echo 'f:fpevent5 vfs_read%return name=(file)$retval->f_path.dentry->d_name.name:string' >> dynamic_events + # 6. Test $current variable support on fprobe + echo 'f:fpevent6 vfs_read pid=$current->pid' >> dynamic_events + echo 'f:fpevent7 vfs_read pid=(task_struct)$current->pid' >> dynamic_events + echo 'f:fpevent8 vfs_read pid=(task_struct,group_leader)$current->pid' >> dynamic_events + + # Test this_cpu_read and this_cpu_ptr on fprobe + echo 'f:fpevent9 sample_timer_cb name=(foo_timer_data,timer)t->name:string count=this_cpu_read((foo_timer_data,timer)t->counter)' >> dynamic_events + echo 'f:fpevent10 sample_timer_cb ptr=this_cpu_ptr((foo_timer_data,timer)t->counter)' >> dynamic_events +fi + +if [ "$KPROBES" ] ; then + # 7. Test basic typecast on kprobe + echo 'p:kpevent1 vfs_read name=(file)file->f_path.dentry->d_name.name:string' >> dynamic_events + # 8. Test parenthesized typecast target on kprobe + echo 'p:kpevent2 vfs_read name=(file)(file)->f_path.dentry->d_name.name:string' >> dynamic_events + # 9. Test nested typecasts on kprobe + echo 'p:kpevent3 vfs_read name=(dentry)((file)file->f_path.dentry)->d_name.name:string' >> dynamic_events + # 10. Test container_of-style typecast with field option on kprobe + echo 'p:kpevent4 vfs_read name=(file,f_path)file->f_mode' >> dynamic_events + # 11. Test typecast on return value on kretprobe + echo 'r:kpevent5 vfs_read name=(file)$retval->f_path.dentry->d_name.name:string' >> dynamic_events + # 12. Test $current variable support on kprobe + echo 'p:kpevent6 vfs_read pid=$current->pid' >> dynamic_events + echo 'p:kpevent7 vfs_read pid=(task_struct)$current->pid' >> dynamic_events + echo 'p:kpevent8 vfs_read pid=(task_struct,group_leader)$current->pid' >> dynamic_events + + # Test this_cpu_read and this_cpu_ptr on kprobe + echo 'p:kpevent9 sample_timer_cb name=(foo_timer_data,timer)t->name:string count=this_cpu_read((foo_timer_data,timer)t->counter)' >> dynamic_events + echo 'p:kpevent10 sample_timer_cb ptr=this_cpu_ptr((foo_timer_data,timer)t->counter)' >> dynamic_events +fi + +# Verify the events exist in dynamic_events +if [ "$FPROBES" ] ; then + grep -q "fpevent1 " dynamic_events + grep -q "fpevent2 " dynamic_events + grep -q "fpevent3 " dynamic_events + grep -q "fpevent4 " dynamic_events + grep -q "fpevent5 " dynamic_events + grep -q "fpevent6 " dynamic_events + grep -q "fpevent7 " dynamic_events + grep -q "fpevent8 " dynamic_events + if lsmod | grep -q trace_events_sample; then + grep -q "fpevent9 " dynamic_events + grep -q "fpevent10 " dynamic_events + fi +fi + +if [ "$KPROBES" ] ; then + grep -q "kpevent1 " dynamic_events + grep -q "kpevent2 " dynamic_events + grep -q "kpevent3 " dynamic_events + grep -q "kpevent4 " dynamic_events + grep -q "kpevent5 " dynamic_events + grep -q "kpevent6 " dynamic_events + grep -q "kpevent7 " dynamic_events + grep -q "kpevent8 " dynamic_events + if lsmod | grep -q trace_events_sample; then + grep -q "kpevent9 " dynamic_events + grep -q "kpevent10 " dynamic_events + fi +fi + +# Clean up +echo > dynamic_events +clear_trace diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/eprobes_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/dynevent/eprobes_syntax_errors.tc index 2a680c086047..c2e3f9d19f13 100644 --- a/tools/testing/selftests/ftrace/test.d/dynevent/eprobes_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/dynevent/eprobes_syntax_errors.tc @@ -10,7 +10,7 @@ check_error() { # command-with-error-pos-by-^ check_error 'e ^a.' # NO_EVENT_INFO check_error 'e ^.b' # NO_EVENT_INFO check_error 'e ^a.b' # BAD_ATTACH_EVENT -check_error 'e syscalls/sys_enter_openat ^foo' # BAD_ATTACH_ARG +check_error 'e syscalls/sys_enter_openat ^foo' # NO_EVENT_FIELD check_error 'e:^/bar syscalls/sys_enter_openat' # NO_GROUP_NAME check_error 'e:^12345678901234567890123456789012345678901234567890123456789012345/bar syscalls/sys_enter_openat' # GROUP_TOO_LONG @@ -19,11 +19,19 @@ check_error 'e:^ syscalls/sys_enter_openat' # NO_EVENT_NAME check_error 'e:foo/^12345678901234567890123456789012345678901234567890123456789012345 syscalls/sys_enter_openat' # EVENT_TOO_LONG check_error 'e:foo/^bar.1 syscalls/sys_enter_openat' # BAD_EVENT_NAME -check_error 'e:foo/bar syscalls/sys_enter_openat arg=^dfd' # BAD_FETCH_ARG check_error 'e:foo/bar syscalls/sys_enter_openat arg=^$foo' # BAD_ATTACH_ARG +check_error 'e:foo/bar syscalls/sys_enter_openat arg=^COMM' # NO_EVENT_FIELD +if grep -q "\$current.*" README; then + check_error 'e:foo/bar syscalls/sys_enter_openat arg=^current' # NO_EVENT_FIELD +fi + if grep -q '<attached-group>\.<attached-event>.*\[if <filter>\]' README; then check_error 'e:foo/bar syscalls/sys_enter_openat if ^' # NO_EP_FILTER fi +if grep -q 'this_cpu_read(<fetcharg>)' README; then + check_error 'e:foo/bar syscalls/sys_enter_openat arg=^this_cpu_read(file)' # NOSUP_PERCPU +fi + exit 0 diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc index fee479295e2f..384209968325 100644 --- a/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_syntax_errors.tc @@ -60,7 +60,7 @@ check_error 'f vfs_read ^&1' # BAD_FETCH_ARG # We've introduced this limitation with array support if grep -q ' <type>\\\[<array-size>\\\]' README; then -check_error 'f vfs_read +0(^+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(@0))))))))))))))' # TOO_MANY_OPS? +check_error 'f vfs_read +0(+0(+0(+0(+0(+0(+0(+0(^+0(@0)))))))))' # TOO_MANY_NESTED check_error 'f vfs_read +0(@11):u8[10^' # ARRAY_NO_CLOSE check_error 'f vfs_read +0(@11):u8[10]^a' # BAD_ARRAY_SUFFIX check_error 'f vfs_read +0(@11):u8[^10a]' # BAD_ARRAY_NUM @@ -75,7 +75,7 @@ check_error 'f vfs_read ^arg123456789012345678901234567890=@11' # ARG_NAME_TOO_L check_error 'f vfs_read ^=@11' # NO_ARG_NAME check_error 'f vfs_read ^var.1=@11' # BAD_ARG_NAME check_error 'f vfs_read var1=@11 ^var1=@12' # USED_ARG_NAME -check_error 'f vfs_read ^+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(@1234))))))' # ARG_TOO_LONG +check_error 'f vfs_read ^+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(@1234))))))))))))))))))))))))))' # ARG_TOO_LONG check_error 'f vfs_read arg1=^' # NO_ARG_BODY @@ -112,6 +112,18 @@ check_error 'f vfs_read%return $retval->^foo' # NO_PTR_STRCT check_error 'f vfs_read file->^foo' # NO_BTF_FIELD check_error 'f vfs_read file^-.foo' # BAD_HYPHEN check_error 'f vfs_read ^file:string' # BAD_TYPE4STR +if grep -qF "[(structname" README ; then +check_error 'f vfs_read arg1=(task_struct)file^' # TYPECAST_REQ_FIELD +check_error 'f vfs_read arg1=(a)((b)((c)((d)((e)((f)((g)((h)(^(i)file->i)->h)->g)->f)->e)->d)->c)->b)->a' # TOO_MANY_NESTED +check_error 'f vfs_read arg1=(task_struct,^in_execve)file->comm' # TYPECAST_NOT_ALIGNED +check_error 'f vfs_read arg1=(task_struct,^foo_bar)file->pid' # NO_BTF_FIELD +check_error 'f vfs_read arg1=(^task_struct1234)file->pid' # NO_PTR_STRCT +check_error 'f vfs_read arg1=(task_struct,se^->group_node)file->comm' # TYPECAST_BAD_ARROW +check_error 'f vfs_read arg1=(task_struct,^->pid)file->comm' # NO_BTF_FIELD +check_error 'f vfs_read arg1=(task_struct,^.pid)file->comm' # NO_BTF_FIELD +check_error 'f vfs_read arg1=(task_struct,^.)file->comm' # NO_BTF_FIELD +check_error 'f vfs_read arg1=(task_struct)^@symbol+10->comm' # TYPECAST_SYM_OFFSET +fi fi else diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/tprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/dynevent/tprobe_syntax_errors.tc index ffe8ffef4027..72b8652df9ba 100644 --- a/tools/testing/selftests/ftrace/test.d/dynevent/tprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/dynevent/tprobe_syntax_errors.tc @@ -46,7 +46,7 @@ check_error 't kfree ^&1' # BAD_FETCH_ARG # We've introduced this limitation with array support if grep -q ' <type>\\\[<array-size>\\\]' README; then -check_error 't kfree +0(^+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(@0))))))))))))))' # TOO_MANY_OPS? +check_error 't kfree +0(+0(+0(+0(+0(+0(+0(+0(^+0(@0)))))))))' # TOO_MANY_NESTED check_error 't kfree +0(@11):u8[10^' # ARRAY_NO_CLOSE check_error 't kfree +0(@11):u8[10]^a' # BAD_ARRAY_SUFFIX check_error 't kfree +0(@11):u8[^10a]' # BAD_ARRAY_NUM @@ -61,7 +61,7 @@ check_error 't kfree ^arg123456789012345678901234567890=@11' # ARG_NAME_TOO_LOG check_error 't kfree ^=@11' # NO_ARG_NAME check_error 't kfree ^var.1=@11' # BAD_ARG_NAME check_error 't kfree var1=@11 ^var1=@12' # USED_ARG_NAME -check_error 't kfree ^+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(@1234))))))' # ARG_TOO_LONG +check_error 't kfree ^+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(@1234))))))))))))))))))))))))))' # ARG_TOO_LONG check_error 't kfree arg1=^' # NO_ARG_BODY diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_module.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_module.tc index 7e74ee11edf9..4b32e1b9a8d3 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_module.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_module.tc @@ -13,6 +13,12 @@ fi MOD=trace_printk FUNC=trace_printk_irq_work +:;: "Add an event on a module function without module name" ;: + +echo "p:event0 $FUNC" > kprobe_events +test -d events/kprobes/event0 || exit_failure +echo "-:kprobes/event0" >> kprobe_events + :;: "Add an event on a module function without specifying event name" ;: echo "p $MOD:$FUNC" > kprobe_events diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc index 8f1c58f0c239..b0e6b80ccb01 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc @@ -56,7 +56,7 @@ check_error 'p vfs_read ^&1' # BAD_FETCH_ARG # We've introduced this limitation with array support if grep -q ' <type>\\\[<array-size>\\\]' README; then -check_error 'p vfs_read +0(^+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(+0(@0))))))))))))))' # TOO_MANY_OPS? +check_error 'p vfs_read +0(+0(+0(+0(+0(+0(+0(+0(^+0(@0)))))))))' # TOO_MANY_NESTED check_error 'p vfs_read +0(@11):u8[10^' # ARRAY_NO_CLOSE check_error 'p vfs_read +0(@11):u8[10]^a' # BAD_ARRAY_SUFFIX check_error 'p vfs_read +0(@11):u8[^10a]' # BAD_ARRAY_NUM @@ -71,7 +71,7 @@ check_error 'p vfs_read ^arg123456789012345678901234567890=@11' # ARG_NAME_TOO_L check_error 'p vfs_read ^=@11' # NO_ARG_NAME check_error 'p vfs_read ^var.1=@11' # BAD_ARG_NAME check_error 'p vfs_read var1=@11 ^var1=@12' # USED_ARG_NAME -check_error 'p vfs_read ^+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(@1234))))))' # ARG_TOO_LONG +check_error 'p vfs_read ^+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(+1234567(@1234))))))))))))))))))))))))))' # ARG_TOO_LONG check_error 'p vfs_read arg1=^' # NO_ARG_BODY # instruction boundary check is valid on x86 (at this moment) @@ -115,6 +115,18 @@ check_error 'p vfs_read+20 ^$arg*' # NOFENTRY_ARGS check_error 'p vfs_read ^hoge' # NO_BTFARG check_error 'p kfree ^$arg10' # NO_BTFARG (exceed the number of parameters) check_error 'r kfree ^$retval' # NO_RETVAL +if grep -qF "[(structname" README ; then +check_error 'p vfs_read arg1=(task_struct)file^' # TYPECAST_REQ_FIELD +check_error 'p vfs_read arg1=(a)((b)((c)((d)((e)((f)((g)((h)(^(i)file->i)->h)->g)->f)->e)->d)->c)->b)->a' # TOO_MANY_NESTED +check_error 'p vfs_read arg1=(task_struct,^in_execve)file->comm' # TYPECAST_NOT_ALIGNED +check_error 'p vfs_read arg1=(task_struct,^foo_bar)file->pid' # NO_BTF_FIELD +check_error 'p vfs_read arg1=(^task_struct1234)file->pid' # NO_PTR_STRCT +check_error 'p vfs_read arg1=(task_struct,se^->group_node)file->comm' # TYPECAST_BAD_ARROW +check_error 'p vfs_read arg1=(task_struct,^->pid)file->comm' # NO_BTF_FIELD +check_error 'p vfs_read arg1=(task_struct,^.pid)file->comm' # NO_BTF_FIELD +check_error 'p vfs_read arg1=(task_struct,^.)file->comm' # NO_BTF_FIELD +check_error 'p vfs_read arg1=(task_struct)^@symbol+10->comm' # TYPECAST_SYM_OFFSET +fi else check_error 'p vfs_read ^$arg*' # NOSUP_BTFARG fi diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc b/tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc index c817158b99db..e12dc967ec76 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc @@ -28,4 +28,9 @@ if grep -q ".*symstr.*" README; then check_error 'p /bin/sh:10 $stack0:^symstr' # BAD_TYPE fi +# $current is not supported by uprobe +if grep -q "\$current.*" README; then +check_error 'p /bin/sh:10 ^$current:u8' # BAD_VAR +fi + exit 0 |
