diff options
author | Steven Rostedt <rostedt@goodmis.org> | 2015-03-24 14:58:13 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-03-26 09:52:29 -0400 |
commit | 7c27f78a297b54c3c2f5075cb15d33431b7f6333 (patch) | |
tree | 20f626ea02fb0590a0946243008f069993bc72d2 /tools | |
parent | 6ebad5c101de0d43dafc9aff88bad45819f10470 (diff) |
tools lib traceevent: Zero should not be considered "not found" in eval_flag()
Guilherme Cox found that:
There is, however, a potential bug if there is an item with code zero
that is not the first one in the symbol list, since eval_flag(..)
returns 0 when it doesn't find anything.
That is, if you have the following enums:
enum {
FOO_START = 0,
FOO_GO = 1,
FOO_END = 2
}
and then have:
__print_symbolic(foo, FOO_GO, "go", FOO_START, "start",
FOO_END, "end")
If none of the enums are known to pevent, then eval_flag() will return
zero, and it will match it to the first item in the list, which would be
FOO_GO, which is not zero.
Luckily, in most cases, the first element would be zero, and the parsing
would match out of sheer luck.
Reported-by: Guilherme Cox <cox@computer.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/20150324145813.0bfe95ba@gandalf.local.home
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index b6d11eea8a57..6d31b6419d37 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -3615,7 +3615,7 @@ static const struct flag flags[] = { | |||
3615 | { "HRTIMER_RESTART", 1 }, | 3615 | { "HRTIMER_RESTART", 1 }, |
3616 | }; | 3616 | }; |
3617 | 3617 | ||
3618 | static unsigned long long eval_flag(const char *flag) | 3618 | static long long eval_flag(const char *flag) |
3619 | { | 3619 | { |
3620 | int i; | 3620 | int i; |
3621 | 3621 | ||
@@ -3631,7 +3631,7 @@ static unsigned long long eval_flag(const char *flag) | |||
3631 | if (strcmp(flags[i].name, flag) == 0) | 3631 | if (strcmp(flags[i].name, flag) == 0) |
3632 | return flags[i].value; | 3632 | return flags[i].value; |
3633 | 3633 | ||
3634 | return 0; | 3634 | return -1LL; |
3635 | } | 3635 | } |
3636 | 3636 | ||
3637 | static void print_str_to_seq(struct trace_seq *s, const char *format, | 3637 | static void print_str_to_seq(struct trace_seq *s, const char *format, |
@@ -3705,7 +3705,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3705 | struct print_flag_sym *flag; | 3705 | struct print_flag_sym *flag; |
3706 | struct format_field *field; | 3706 | struct format_field *field; |
3707 | struct printk_map *printk; | 3707 | struct printk_map *printk; |
3708 | unsigned long long val, fval; | 3708 | long long val, fval; |
3709 | unsigned long addr; | 3709 | unsigned long addr; |
3710 | char *str; | 3710 | char *str; |
3711 | unsigned char *hex; | 3711 | unsigned char *hex; |
@@ -3764,11 +3764,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3764 | print = 0; | 3764 | print = 0; |
3765 | for (flag = arg->flags.flags; flag; flag = flag->next) { | 3765 | for (flag = arg->flags.flags; flag; flag = flag->next) { |
3766 | fval = eval_flag(flag->value); | 3766 | fval = eval_flag(flag->value); |
3767 | if (!val && !fval) { | 3767 | if (!val && fval < 0) { |
3768 | print_str_to_seq(s, format, len_arg, flag->str); | 3768 | print_str_to_seq(s, format, len_arg, flag->str); |
3769 | break; | 3769 | break; |
3770 | } | 3770 | } |
3771 | if (fval && (val & fval) == fval) { | 3771 | if (fval > 0 && (val & fval) == fval) { |
3772 | if (print && arg->flags.delim) | 3772 | if (print && arg->flags.delim) |
3773 | trace_seq_puts(s, arg->flags.delim); | 3773 | trace_seq_puts(s, arg->flags.delim); |
3774 | print_str_to_seq(s, format, len_arg, flag->str); | 3774 | print_str_to_seq(s, format, len_arg, flag->str); |