Re: [PATCH] tracing: Fix synth event printk format for str fields

From: Douglas Raillard
Date: Wed Mar 19 2025 - 10:36:47 EST


Hi,

On 19-03-2025 12:18, Masami Hiramatsu (Google) wrote:
Hi,

On Tue, 18 Mar 2025 18:09:38 +0000
Douglas RAILLARD <douglas.raillard@xxxxxxx> wrote:

From: Douglas Raillard <douglas.raillard@xxxxxxx>

The printk format for synth event uses "%.*s" to print string fields,
but then only passes the pointer part as var arg.

Add the missing precision var arg.

I'm not sure what you want to. Would you mean showing the string length too?
But I think actual output(*) shows only string, right?

(*) the output data which can be read from `trace` file.

The "%.*s" printf/printk format specifier has 2 components:
1. the "*" part that in printf documentation called the "precision"
2. the "s" part that is called the "specifier"

For a "s" specifier, the precision is interpreted as the number of chars to display from that string.
In any case, using "*" as precision means the value is passed dynamically, as a parameter to printf/printk,
before the actual char *. Both those args are consumed by printk to display "%.*s", the precision is never
displayed on its own.

In the current state, synthetic event use "%.*s" for string fields, but then only a single `__get_str(field)`
is passed to printk, so it's missing the precision arg. Both trace-cmd and our parser report an error because of that.

The alternative would be to just use "%s" instead of "%.*s", but I assume whoever wrote the code initially had a reason
to use the precision (maybe to print non-null-terminated strings ?), so I simply fixed the arguments.


Thank you,


Signed-off-by: Douglas Raillard <douglas.raillard@xxxxxxx>
---
kernel/trace/trace_events_synth.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index e3f7d09e5512..274b9b1d9f7d 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -620,7 +620,8 @@ static int __set_synth_event_print_fmt(struct synth_event *event,
if (event->fields[i]->is_string &&
event->fields[i]->is_dynamic)
pos += snprintf(buf + pos, LEN_OR_ZERO,
- ", __get_str(%s)", event->fields[i]->name);
+ ", (int)__get_dynamic_array_len(%s), __get_str(%s)",
+ event->fields[i]->name, event->fields[i]->name);
else if (event->fields[i]->is_stack)
pos += snprintf(buf + pos, LEN_OR_ZERO,
", __get_stacktrace(%s)", event->fields[i]->name);
--
2.43.0