diff options
author | David Daney <ddaney@caviumnetworks.com> | 2010-07-22 17:05:05 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2010-07-23 11:10:05 -0400 |
commit | 2e5b970e1dbd1ecb5eb8db292604b98e0c22525a (patch) | |
tree | d6b4ee1bb3e8c22267544cca110de839a30f1b47 | |
parent | 9f267e38f246a727b164dd6418aedabc74fb71b0 (diff) |
trace-cmd: Don't SIGSEGV when event field format cannot be parsed (v2).
print fmt: "page=%p pfn=%lu order=%d migratetype=%d", REC->page, ({ struct page *__pg = (REC->page); int __sec = page_to_section(__pg); (unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); }), REC->order, REC->migratetype
This cannot be parsed, leading to a NULL struct event_format* being
passed to pevent_get_common_field_val, which produces a SIGSEGV. It
would be good to get a parsable format from the kernel, but to
remediate the problem for legacy kernels, we can just return an error
indicator in this case. This allows some output from trace-cmd
report, although perhaps with some missing data. But this is better
than crashing.
(v2): Do the check in all pevent_get_*
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
LKML-Reference: <1279832705-14219-1-git-send-email-ddaney@caviumnetworks.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | parse-events.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/parse-events.c b/parse-events.c index 1e854e2..595ba90 100644 --- a/parse-events.c +++ b/parse-events.c | |||
@@ -4464,6 +4464,9 @@ int pevent_get_field_val(struct trace_seq *s, struct event_format *event, | |||
4464 | { | 4464 | { |
4465 | struct format_field *field; | 4465 | struct format_field *field; |
4466 | 4466 | ||
4467 | if (!event) | ||
4468 | return -1; | ||
4469 | |||
4467 | field = pevent_find_field(event, name); | 4470 | field = pevent_find_field(event, name); |
4468 | 4471 | ||
4469 | return get_field_val(s, field, name, record, val, err); | 4472 | return get_field_val(s, field, name, record, val, err); |
@@ -4486,6 +4489,9 @@ int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event, | |||
4486 | { | 4489 | { |
4487 | struct format_field *field; | 4490 | struct format_field *field; |
4488 | 4491 | ||
4492 | if (!event) | ||
4493 | return -1; | ||
4494 | |||
4489 | field = pevent_find_common_field(event, name); | 4495 | field = pevent_find_common_field(event, name); |
4490 | 4496 | ||
4491 | return get_field_val(s, field, name, record, val, err); | 4497 | return get_field_val(s, field, name, record, val, err); |
@@ -4508,6 +4514,9 @@ int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event, | |||
4508 | { | 4514 | { |
4509 | struct format_field *field; | 4515 | struct format_field *field; |
4510 | 4516 | ||
4517 | if (!event) | ||
4518 | return -1; | ||
4519 | |||
4511 | field = pevent_find_any_field(event, name); | 4520 | field = pevent_find_any_field(event, name); |
4512 | 4521 | ||
4513 | return get_field_val(s, field, name, record, val, err); | 4522 | return get_field_val(s, field, name, record, val, err); |