perf trace: Handle perf.data files with no tracepoints
authorArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 6 Sep 2013 18:19:01 +0000 (15:19 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 9 Sep 2013 18:50:44 +0000 (15:50 -0300)
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>
tools/perf/util/session.c

index 476caa1..0308d9e 100644 (file)
@@ -1620,52 +1620,26 @@ int __perf_session__set_tracepoints_handlers(struct perf_session *session,
                                             const struct perf_evsel_str_handler *assocs,
                                             size_t nr_assocs)
 {
-       struct perf_evlist *evlist = session->evlist;
-       struct event_format *format;
        struct perf_evsel *evsel;
-       char *tracepoint, *name;
        size_t i;
        int err;
 
        for (i = 0; i < nr_assocs; i++) {
-               err = -ENOMEM;
-               tracepoint = strdup(assocs[i].name);
-               if (tracepoint == NULL)
-                       goto out;
-
-               err = -ENOENT;
-               name = strchr(tracepoint, ':');
-               if (name == NULL)
-                       goto out_free;
-
-               *name++ = '\0';
-               format = pevent_find_event_by_name(session->pevent,
-                                                  tracepoint, name);
-               if (format == NULL) {
-                       /*
-                        * Adding a handler for an event not in the session,
-                        * just ignore it.
-                        */
-                       goto next;
-               }
-
-               evsel = perf_evlist__find_tracepoint_by_id(evlist, format->id);
+               /*
+                * Adding a handler for an event not in the session,
+                * just ignore it.
+                */
+               evsel = perf_evlist__find_tracepoint_by_name(session->evlist, assocs[i].name);
                if (evsel == NULL)
-                       goto next;
+                       continue;
 
                err = -EEXIST;
                if (evsel->handler.func != NULL)
-                       goto out_free;
+                       goto out;
                evsel->handler.func = assocs[i].handler;
-next:
-               free(tracepoint);
        }
 
        err = 0;
 out:
        return err;
-
-out_free:
-       free(tracepoint);
-       goto out;
 }