tracing: Fix number printing bug in print_synth_event()
Fix a varargs-related bug in print_synth_event() which resulted in strange output and oopses on 32-bit x86 systems. The problem is that trace_seq_printf() expects the varargs to match the format string, but print_synth_event() was always passing u64 values regardless. This results in unspecified behavior when unpacking with va_arg() in trace_seq_printf(). Add a function that takes the size into account when calling trace_seq_printf(). Before: modprobe-1731 [003] .... 919.039758: gen_synth_test: next_pid_field=777(null)next_comm_field=hula hoops ts_ns=1000000 ts_ms=1000 cpu=3(null)my_string_field=thneed my_int_field=598(null) After: insmod-1136 [001] .... 36.634590: gen_synth_test: next_pid_field=777 next_comm_field=hula hoops ts_ns=1000000 ts_ms=1000 cpu=1 my_string_field=thneed my_int_field=598 Link: http://lkml.kernel.org/r/a9b59eb515dbbd7d4abe53b347dccf7a8e285657.1581720155.git.zanussi@kernel.org Reported-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Signed-off-by: Tom Zanussi <zanussi@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
parent
3843083772
commit
784bd0847e
|
@ -820,6 +820,29 @@ static const char *synth_field_fmt(char *type)
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_synth_event_num_val(struct trace_seq *s,
|
||||||
|
char *print_fmt, char *name,
|
||||||
|
int size, u64 val, char *space)
|
||||||
|
{
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
trace_seq_printf(s, print_fmt, name, (u8)val, space);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
trace_seq_printf(s, print_fmt, name, (u16)val, space);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
trace_seq_printf(s, print_fmt, name, (u32)val, space);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
trace_seq_printf(s, print_fmt, name, val, space);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static enum print_line_t print_synth_event(struct trace_iterator *iter,
|
static enum print_line_t print_synth_event(struct trace_iterator *iter,
|
||||||
int flags,
|
int flags,
|
||||||
struct trace_event *event)
|
struct trace_event *event)
|
||||||
|
@ -858,10 +881,13 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter,
|
||||||
} else {
|
} else {
|
||||||
struct trace_print_flags __flags[] = {
|
struct trace_print_flags __flags[] = {
|
||||||
__def_gfpflag_names, {-1, NULL} };
|
__def_gfpflag_names, {-1, NULL} };
|
||||||
|
char *space = (i == se->n_fields - 1 ? "" : " ");
|
||||||
|
|
||||||
trace_seq_printf(s, print_fmt, se->fields[i]->name,
|
print_synth_event_num_val(s, print_fmt,
|
||||||
|
se->fields[i]->name,
|
||||||
|
se->fields[i]->size,
|
||||||
entry->fields[n_u64],
|
entry->fields[n_u64],
|
||||||
i == se->n_fields - 1 ? "" : " ");
|
space);
|
||||||
|
|
||||||
if (strcmp(se->fields[i]->type, "gfp_t") == 0) {
|
if (strcmp(se->fields[i]->type, "gfp_t") == 0) {
|
||||||
trace_seq_puts(s, " (");
|
trace_seq_puts(s, " (");
|
||||||
|
|
Loading…
Reference in New Issue