diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-09-06 14:19:01 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-09-09 14:50:44 -0400 |
commit | ccf53eac2097fb47bc40875ffb22c2d10fa8c46c (patch) | |
tree | 66a3953917d06265a9bac53e71a95d9f4757f62a /tools | |
parent | 72f4a11d2fb16792f5e5107922652366194cfd66 (diff) |
perf trace: Handle perf.data files with no tracepoints
Before:
perf trace -i perf.data
Segmentation fault (core dumped)
#
After:
# perf trace -i perf.data
Data file does not have raw_syscalls:sys_enter events
#
When there are no tracepoints in a perf.data file the struct pevent
that contains the list of tracepoints that will be used to lookup the
tracepoint id by name will not be populated, causing a NULL deref.
And we don't need to do all that dance to look at pevents for an entry
with a slighly different name to then lookup the tracepoint by its id on
the evlist, just use the perf_evlist__find_tracepoint_by_name() routine,
that will find the tracepoint, if present.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-egcm21k1e6gcyxpcgjxtmsq3@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/session.c | 40 |
1 files changed, 7 insertions, 33 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 476caa129a20..0308d9ee7a77 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -1620,52 +1620,26 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session, | |||
1620 | const struct perf_evsel_str_handler *assocs, | 1620 | const struct perf_evsel_str_handler *assocs, |
1621 | size_t nr_assocs) | 1621 | size_t nr_assocs) |
1622 | { | 1622 | { |
1623 | struct perf_evlist *evlist = session->evlist; | ||
1624 | struct event_format *format; | ||
1625 | struct perf_evsel *evsel; | 1623 | struct perf_evsel *evsel; |
1626 | char *tracepoint, *name; | ||
1627 | size_t i; | 1624 | size_t i; |
1628 | int err; | 1625 | int err; |
1629 | 1626 | ||
1630 | for (i = 0; i < nr_assocs; i++) { | 1627 | for (i = 0; i < nr_assocs; i++) { |
1631 | err = -ENOMEM; | 1628 | /* |
1632 | tracepoint = strdup(assocs[i].name); | 1629 | * Adding a handler for an event not in the session, |
1633 | if (tracepoint == NULL) | 1630 | * just ignore it. |
1634 | goto out; | 1631 | */ |
1635 | 1632 | evsel = perf_evlist__find_tracepoint_by_name(session->evlist, assocs[i].name); | |
1636 | err = -ENOENT; | ||
1637 | name = strchr(tracepoint, ':'); | ||
1638 | if (name == NULL) | ||
1639 | goto out_free; | ||
1640 | |||
1641 | *name++ = '\0'; | ||
1642 | format = pevent_find_event_by_name(session->pevent, | ||
1643 | tracepoint, name); | ||
1644 | if (format == NULL) { | ||
1645 | /* | ||
1646 | * Adding a handler for an event not in the session, | ||
1647 | * just ignore it. | ||
1648 | */ | ||
1649 | goto next; | ||
1650 | } | ||
1651 | |||
1652 | evsel = perf_evlist__find_tracepoint_by_id(evlist, format->id); | ||
1653 | if (evsel == NULL) | 1633 | if (evsel == NULL) |
1654 | goto next; | 1634 | continue; |
1655 | 1635 | ||
1656 | err = -EEXIST; | 1636 | err = -EEXIST; |
1657 | if (evsel->handler.func != NULL) | 1637 | if (evsel->handler.func != NULL) |
1658 | goto out_free; | 1638 | goto out; |
1659 | evsel->handler.func = assocs[i].handler; | 1639 | evsel->handler.func = assocs[i].handler; |
1660 | next: | ||
1661 | free(tracepoint); | ||
1662 | } | 1640 | } |
1663 | 1641 | ||
1664 | err = 0; | 1642 | err = 0; |
1665 | out: | 1643 | out: |
1666 | return err; | 1644 | return err; |
1667 | |||
1668 | out_free: | ||
1669 | free(tracepoint); | ||
1670 | goto out; | ||
1671 | } | 1645 | } |