@@ -1002,6 +1002,54 @@ static size_t btf_enum_scnprintf(const struct btf_type *type, struct btf *btf, c
1002
1002
return 0 ;
1003
1003
}
1004
1004
1005
+ struct trace_btf_dump_snprintf_ctx {
1006
+ char * bf ;
1007
+ size_t printed , size ;
1008
+ };
1009
+
1010
+ static void trace__btf_dump_snprintf (void * vctx , const char * fmt , va_list args )
1011
+ {
1012
+ struct trace_btf_dump_snprintf_ctx * ctx = vctx ;
1013
+
1014
+ ctx -> printed += vscnprintf (ctx -> bf + ctx -> printed , ctx -> size - ctx -> printed , fmt , args );
1015
+ }
1016
+
1017
+ static size_t btf_struct_scnprintf (const struct btf_type * type , struct btf * btf , char * bf , size_t size , struct syscall_arg * arg )
1018
+ {
1019
+ struct trace_btf_dump_snprintf_ctx ctx = {
1020
+ .bf = bf ,
1021
+ .size = size ,
1022
+ };
1023
+ struct augmented_arg * augmented_arg = arg -> augmented .args ;
1024
+ int type_id = arg -> fmt -> type_id , consumed ;
1025
+ struct btf_dump * btf_dump ;
1026
+
1027
+ LIBBPF_OPTS (btf_dump_opts , dump_opts );
1028
+ LIBBPF_OPTS (btf_dump_type_data_opts , dump_data_opts );
1029
+
1030
+ if (arg == NULL || arg -> augmented .args == NULL )
1031
+ return 0 ;
1032
+
1033
+ dump_data_opts .compact = true;
1034
+ dump_data_opts .skip_names = !arg -> trace -> show_arg_names ;
1035
+
1036
+ btf_dump = btf_dump__new (btf , trace__btf_dump_snprintf , & ctx , & dump_opts );
1037
+ if (btf_dump == NULL )
1038
+ return 0 ;
1039
+
1040
+ /* pretty print the struct data here */
1041
+ if (btf_dump__dump_type_data (btf_dump , type_id , arg -> augmented .args -> value , type -> size , & dump_data_opts ) == 0 )
1042
+ return 0 ;
1043
+
1044
+ consumed = sizeof (* augmented_arg ) + augmented_arg -> size ;
1045
+ arg -> augmented .args = ((void * )arg -> augmented .args ) + consumed ;
1046
+ arg -> augmented .size -= consumed ;
1047
+
1048
+ btf_dump__free (btf_dump );
1049
+
1050
+ return ctx .printed ;
1051
+ }
1052
+
1005
1053
static size_t trace__btf_scnprintf (struct trace * trace , struct syscall_arg * arg , char * bf ,
1006
1054
size_t size , int val , char * type )
1007
1055
{
@@ -1021,6 +1069,8 @@ static size_t trace__btf_scnprintf(struct trace *trace, struct syscall_arg *arg,
1021
1069
1022
1070
if (btf_is_enum (arg_fmt -> type ))
1023
1071
return btf_enum_scnprintf (arg_fmt -> type , trace -> btf , bf , size , val );
1072
+ else if (btf_is_struct (arg_fmt -> type ))
1073
+ return btf_struct_scnprintf (arg_fmt -> type , trace -> btf , bf , size , arg );
1024
1074
1025
1075
return 0 ;
1026
1076
}
@@ -2236,6 +2286,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
2236
2286
.show_string_prefix = trace -> show_string_prefix ,
2237
2287
};
2238
2288
struct thread_trace * ttrace = thread__priv (thread );
2289
+ void * default_scnprintf ;
2239
2290
2240
2291
/*
2241
2292
* Things like fcntl will set this in its 'cmd' formatter to pick the
@@ -2277,11 +2328,15 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
2277
2328
if (trace -> show_arg_names )
2278
2329
printed += scnprintf (bf + printed , size - printed , "%s: " , field -> name );
2279
2330
2280
- btf_printed = trace__btf_scnprintf (trace , & arg , bf + printed ,
2281
- size - printed , val , field -> type );
2282
- if (btf_printed ) {
2283
- printed += btf_printed ;
2284
- continue ;
2331
+ default_scnprintf = sc -> arg_fmt [arg .idx ].scnprintf ;
2332
+
2333
+ if (default_scnprintf == NULL || default_scnprintf == SCA_PTR ) {
2334
+ btf_printed = trace__btf_scnprintf (trace , & arg , bf + printed ,
2335
+ size - printed , val , field -> type );
2336
+ if (btf_printed ) {
2337
+ printed += btf_printed ;
2338
+ continue ;
2339
+ }
2285
2340
}
2286
2341
2287
2342
printed += syscall_arg_fmt__scnprintf_val (& sc -> arg_fmt [arg .idx ],
0 commit comments