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); |
