Probes updates for v6.15:

- probe-events: Add comments about entry data storing code to clarify
   where and how the entry data is stored for function return events.
 
 - probe-events: Log error for exceeding the number of arguments to help
   user to identify error reason via tracefs/error_log file.
 
 - selftests/ftrace: Improve the ftracetest to add followngs.
   . Expand the tprobe event test to check if it can correctly find
     the wrong format tracepoint name.
   . Add new syntax error test to check whether error_log correctly
     indicates a wrong character in the tracepoint name.
   . Add a new dynamic events argument limitation test case which checks
     max number of probe arguments.
 -----BEGIN PGP SIGNATURE-----
 
 iQFPBAABCgA5FiEEh7BulGwFlgAOi5DV2/sHvwUrPxsFAmflTlobHG1hc2FtaS5o
 aXJhbWF0c3VAZ21haWwuY29tAAoJENv7B78FKz8ba9UIALzzZQxzUhJYO/B/XaCz
 KTuSrU2594cLr3nCrmCfL3UHUCr5IcjXKCfUdrgzE9mckWF+nVRXWwbp29KpOQky
 fzU9Ardbr7ksGAYFk4My+P/BeYa7vh9LwofXzWlJibANVxWvq66+GfKnWnh1P8Bl
 /zjov61DAEQmDfXNGZ2oTmKnYYMoPkJU4voRvAEUgiP02SrF04UUa00uC7hmZJJV
 aI5b6TatE5FDEmAoHWh0cf04HoyevRyLVOQd5GSswH/oWpyhs90M7a9WENHamBx6
 RXEZ3xYyuH9zBSvYVeRn2H1eHnGCR4RMctZiRGXF8EdLWo7RXRQ1Hp9CgvwDrU8Z
 IL0=
 =vZ3e
 -----END PGP SIGNATURE-----

Merge tag 'probes-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull probes updates from Masami Hiramatsu:

 - probe-events: Add comments about entry data storing code to clarify
   where and how the entry data is stored for function return events.

 - probe-events: Log error for exceeding the number of arguments to help
   user to identify error reason via tracefs/error_log file.

 - Improve the ftracetest selftests:
    - Expand the tprobe event test to check if it can correctly find the
      wrong format tracepoint name.
    - Add new syntax error test to check whether error_log correctly
      indicates a wrong character in the tracepoint name.
    - Add a new dynamic events argument limitation test case which
      checks max number of probe arguments.

* tag 'probes-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tracing: probe-events: Add comments about entry data storing code
  selftests/ftrace: Add dynamic events argument limitation test case
  selftests/ftrace: Add new syntax error test
  selftests/ftrace: Expand the tprobe event test to check wrong format
  tracing: probe-events: Log error for exceeding the number of arguments
This commit is contained in:
Linus Torvalds 2025-03-27 19:31:34 -07:00
commit a7e135fe59
9 changed files with 103 additions and 4 deletions

View File

@ -913,6 +913,8 @@ static int __trace_eprobe_create(int argc, const char *argv[])
}
if (argc - 2 > MAX_TRACE_ARGS) {
trace_probe_log_set_index(2);
trace_probe_log_err(0, TOO_MANY_ARGS);
ret = -E2BIG;
goto error;
}

View File

@ -1199,8 +1199,11 @@ static int trace_fprobe_create_internal(int argc, const char *argv[],
argc = new_argc;
argv = new_argv;
}
if (argc > MAX_TRACE_ARGS)
if (argc > MAX_TRACE_ARGS) {
trace_probe_log_set_index(2);
trace_probe_log_err(0, TOO_MANY_ARGS);
return -E2BIG;
}
ret = traceprobe_expand_dentry_args(argc, argv, &dbuf);
if (ret)

View File

@ -1007,8 +1007,11 @@ static int trace_kprobe_create_internal(int argc, const char *argv[],
argc = new_argc;
argv = new_argv;
}
if (argc > MAX_TRACE_ARGS)
if (argc > MAX_TRACE_ARGS) {
trace_probe_log_set_index(2);
trace_probe_log_err(0, TOO_MANY_ARGS);
return -E2BIG;
}
ret = traceprobe_expand_dentry_args(argc, argv, &dbuf);
if (ret)

View File

@ -770,6 +770,10 @@ static int check_prepare_btf_string_fetch(char *typename,
#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
/*
* Add the entry code to store the 'argnum'th parameter and return the offset
* in the entry data buffer where the data will be stored.
*/
static int __store_entry_arg(struct trace_probe *tp, int argnum)
{
struct probe_entry_arg *earg = tp->entry_arg;
@ -793,6 +797,20 @@ static int __store_entry_arg(struct trace_probe *tp, int argnum)
tp->entry_arg = earg;
}
/*
* The entry code array is repeating the pair of
* [FETCH_OP_ARG(argnum)][FETCH_OP_ST_EDATA(offset of entry data buffer)]
* and the rest of entries are filled with [FETCH_OP_END].
*
* To reduce the redundant function parameter fetching, we scan the entry
* code array to find the FETCH_OP_ARG which already fetches the 'argnum'
* parameter. If it doesn't match, update 'offset' to find the last
* offset.
* If we find the FETCH_OP_END without matching FETCH_OP_ARG entry, we
* will save the entry with FETCH_OP_ARG and FETCH_OP_ST_EDATA, and
* return data offset so that caller can find the data offset in the entry
* data buffer.
*/
offset = 0;
for (i = 0; i < earg->size - 1; i++) {
switch (earg->code[i].op) {
@ -826,6 +844,16 @@ int traceprobe_get_entry_data_size(struct trace_probe *tp)
if (!earg)
return 0;
/*
* earg->code[] array has an operation sequence which is run in
* the entry handler.
* The sequence stopped by FETCH_OP_END and each data stored in
* the entry data buffer by FETCH_OP_ST_EDATA. The FETCH_OP_ST_EDATA
* stores the data at the data buffer + its offset, and all data are
* "unsigned long" size. The offset must be increased when a data is
* stored. Thus we need to find the last FETCH_OP_ST_EDATA in the
* code array.
*/
for (i = 0; i < earg->size; i++) {
switch (earg->code[i].op) {
case FETCH_OP_END:

View File

@ -545,6 +545,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call,
C(BAD_BTF_TID, "Failed to get BTF type info."),\
C(BAD_TYPE4STR, "This type does not fit for string."),\
C(NEED_STRING_TYPE, "$comm and immediate-string only accepts string type"),\
C(TOO_MANY_ARGS, "Too many arguments are specified"), \
C(TOO_MANY_EARGS, "Too many entry arguments specified"),
#undef C

View File

@ -562,8 +562,14 @@ static int __trace_uprobe_create(int argc, const char **argv)
if (argc < 2)
return -ECANCELED;
if (argc - 2 > MAX_TRACE_ARGS)
trace_probe_log_init("trace_uprobe", argc, argv);
if (argc - 2 > MAX_TRACE_ARGS) {
trace_probe_log_set_index(2);
trace_probe_log_err(0, TOO_MANY_ARGS);
return -E2BIG;
}
if (argv[0][1] == ':')
event = &argv[0][2];
@ -582,7 +588,6 @@ static int __trace_uprobe_create(int argc, const char **argv)
return -ECANCELED;
}
trace_probe_log_init("trace_uprobe", argc, argv);
trace_probe_log_set_index(1); /* filename is the 2nd argument */
*arg++ = '\0';

View File

@ -6,6 +6,7 @@
echo 0 > events/enable
echo > dynamic_events
SUBSYSTEM=kmem
TRACEPOINT1=kmem_cache_alloc
TRACEPOINT2=kmem_cache_free
@ -24,4 +25,17 @@ grep -q myevent1 dynamic_events
echo > dynamic_events
# auto naming check
echo "t $TRACEPOINT1" >> dynamic_events
test -d events/tracepoints/$TRACEPOINT1
echo > dynamic_events
# SUBSYSTEM is not supported
echo "t $SUBSYSTEM/$TRACEPOINT1" >> dynamic_events && exit_fail ||:
echo "t $SUBSYSTEM:$TRACEPOINT1" >> dynamic_events && exit_fail ||:
echo "t:myevent3 $SUBSYSTEM/$TRACEPOINT1" >> dynamic_events && exit_fail ||:
echo "t:myevent3 $SUBSYSTEM:$TRACEPOINT1" >> dynamic_events && exit_fail ||:
clear_trace

View File

@ -0,0 +1,42 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Checking dynamic events limitations
# requires: dynamic_events "imm-value":README
# Max arguments limitation
MAX_ARGS=128
EXCEED_ARGS=$((MAX_ARGS + 1))
check_max_args() { # event_header
TEST_STRING=$1
# Acceptable
for i in `seq 1 $MAX_ARGS`; do
TEST_STRING="$TEST_STRING \\$i"
done
echo "$TEST_STRING" >> dynamic_events
echo > dynamic_events
# Error
TEST_STRING="$TEST_STRING \\$EXCEED_ARGS"
! echo "$TEST_STRING" >> dynamic_events
return 0
}
# Kprobe max args limitation
if grep -q "kprobe_events" README; then
check_max_args "p vfs_read"
fi
# Fprobe max args limitation
if grep -q "f[:[<group>/][<event>]] <func-name>[%return] [<args>]" README; then
check_max_args "f vfs_read"
fi
# Tprobe max args limitation
if grep -q "t[:[<group>/][<event>]] <tracepoint> [<args>]" README; then
check_max_args "t kfree"
fi
# Uprobe max args limitation
if grep -q "uprobe_events" README; then
check_max_args "p /bin/sh:10"
fi

View File

@ -27,6 +27,7 @@ check_error 'f:^foo.1/bar vfs_read' # BAD_GROUP_NAME
check_error 'f:^ vfs_read' # NO_EVENT_NAME
check_error 'f:foo/^12345678901234567890123456789012345678901234567890123456789012345 vfs_read' # EVENT_TOO_LONG
check_error 'f:foo/^bar.1 vfs_read' # BAD_EVENT_NAME
check_error 't kmem^/kfree' # BAD_TP_NAME
check_error 'f vfs_read ^$stack10000' # BAD_STACK_NUM