Re: [PATCH v4 2/4] ftrace: Add support for function argument to graph tracer

From: Google
Date: Sun Apr 13 2025 - 23:09:20 EST


On Fri, 11 Apr 2025 15:13:58 -0400
Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:

> On Fri, 11 Apr 2025 14:31:32 -0400
> Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:
>
> > Hmm, I just tested this, and it fails on my box too (I test on a debian VM).
> >
> > It fails with and without setting it to bash. I'll take a look too.
>
> Hmm, maybe it is a bashism.
>
> The test has this:
>
> # 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
>
> So I tried manually executing this in bash:
>
> --------------------------8<--------------------------
> # TEST_STRING='p vfs_read'
> # for i in `seq 1 128`; do TEST_STRING="$TEST_STRING \\$i" ; done
> # echo $TEST_STRING
> p vfs_read \1 \2 \3 \4 \5 \6 \7 \8 \9 \10 \11 \12 \13 \14 \15 \16 \17 \18 \19 \20 \21 \22 \23 \24 \25 \26 \27 \28 \29 \30 \31 \32 \33 \34 \35 \36 \37 \38 \39 \40 \41 \42 \43 \44 \45 \46 \47 \48 \49 \50 \51 \52 \53 \54 \55 \56 \57 \58 \59 \60 \61 \62 \63 \64 \65 \66 \67 \68 \69 \70 \71 \72 \73 \74 \75 \76 \77 \78 \79 \80 \81 \82 \83 \84 \85 \86 \87 \88 \89 \90 \91 \92 \93 \94 \95 \96 \97 \98 \99 \100 \101 \102 \103 \104 \105 \106 \107 \108 \109 \110 \111 \112 \113 \114 \115 \116 \117 \118 \119 \120 \121 \122 \123 \124 \125 \126 \127 \128
> # echo "$TEST_STRING" >> /sys/kernel/tracing/dynamic_events
> # echo $?
> 0
> # cat /sys/kernel/tracing/dynamic_events
> p:kprobes/p_vfs_read_0 vfs_read arg1=\1 arg2=\2 arg3=\3 arg4=\4 arg5=\5 arg6=\6 arg7=\7 arg8=\8 arg9=\9 arg10=\10 arg11=\11 arg12=\12 arg13=\13 arg14=\14 arg15=\15 arg16=\16 arg17=\17 arg18=\18 arg19=\19 arg20=\20 arg21=\21 arg22=\22 arg23=\23 arg24=\24 arg25=\25 arg26=\26 arg27=\27 arg28=\28 arg29=\29 arg30=\30 arg31=\31 arg32=\32 arg33=\33 arg34=\34 arg35=\35 arg36=\36 arg37=\37 arg38=\38 arg39=\39 arg40=\40 arg41=\41 arg42=\42 arg43=\43 arg44=\44 arg45=\45 arg46=\46 arg47=\47 arg48=\48 arg49=\49 arg50=\50 arg51=\51 arg52=\52 arg53=\53 arg54=\54 arg55=\55 arg56=\56 arg57=\57 arg58=\58 arg59=\59 arg60=\60 arg61=\61 arg62=\62 arg63=\63 arg64=\64 arg65=\65 arg66=\66 arg67=\67 arg68=\68 arg69=\69 arg70=\70 arg71=\71 arg72=\72 arg73=\73 arg74=\74 arg75=\75 arg76=\76 arg77=\77 arg78=\78 arg79=\79 arg80=\80 arg81=\81 arg82=\82 arg83=\83 arg84=\84 arg85=\85 arg86=\86 arg87=\87 arg88=\88 arg89=\89 arg90=\90 arg91=\91 arg92=\92 arg93=\93 arg94=\94 arg95=\95 arg96=\96 arg97=\97 arg98=\98 ar
g99=\99 arg100=\100 arg101=\101 arg102=\102 arg103=\103 arg104=\104 arg105=\105 arg106=\106 arg107=\107 arg108=\108 arg109=\109 arg110=\110 arg111=\111 arg112=\112 arg113=\113 arg114=\114 arg115=\115 arg116=\116 arg117=\117 arg118=\118 arg119=\119 arg120=\120 arg121=\121 arg122=\122 arg123=\123 arg124=\124 arg125=\125 arg126=\126 arg127=\127 arg128=\128
> -------------------------->8--------------------------
>
> Doing the same in dash:
>
> --------------------------8<--------------------------
> # dash
> # TEST_STRING='p vfs_read'
> # for i in `seq 1 128`; do TEST_STRING="$TEST_STRING \\$i" ; done
> # echo $TEST_STRING
> p vfs_read \8 \9
>
>
> 8 9 8 9 ␦ 9 ! " # $ % & ' 8 9 ( ) * + , - . / 8 9 0 1 2 3 4 5 6 7 8 9 8 9 : ; < = > ? 8 9 \80 \81 \82 \83 \84 \85 \86 \87 \88 \89 \90 \91 \92 \93 \94 \95 \96 \97 \98 \99 @ A B C D E F G89 H I J K L M N O 8 9 P Q R S T U V W
> 8
> # echo "$TEST_STRING" >> /sys/kernel/tracing/dynamic_events
> dash: 8: echo: echo: I/O error
> -------------------------->8--------------------------

Oops...

>
> Looks like dash will translate those "\#" into the ASCII equivalent,
> whereas bash does not.

Ah, I didn't know that.

>
> This patch seems to fix it:
>
> diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/dynevent_limitations.tc b/tools/testing/selftests/ftrace/test.d/dynevent/dynevent_limitations.tc
> index 6b94b678741a..ebe2a34cbf92 100644
> --- a/tools/testing/selftests/ftrace/test.d/dynevent/dynevent_limitations.tc
> +++ b/tools/testing/selftests/ftrace/test.d/dynevent/dynevent_limitations.tc
> @@ -11,7 +11,7 @@ check_max_args() { # event_header
> TEST_STRING=$1
> # Acceptable
> for i in `seq 1 $MAX_ARGS`; do
> - TEST_STRING="$TEST_STRING \\$i"
> + TEST_STRING="$TEST_STRING \\\\$i"
> done
> echo "$TEST_STRING" >> dynamic_events
> echo > dynamic_events
>
>
> Masami, you just recently added this test (it's dated March 27th 2025), did
> you mean to write in the ASCII characters? Why the backslash?

No, the kprobe_event accepts raw digit values to record in the trace buffer
which is for the probe points which uses a fixed digit value for the actual
local variable (or function parameter), e.g. constant propagation with
optimized function instances.

In this case, can we use below?

TEST_STRING="$TEST_STRING "'\\'$i


Thank you,

>
> -- Steve
>


--
Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx>