perf tools: Propagate event parse error handling
authorFrederic Weisbecker <fweisbec@gmail.com>
Sun, 22 May 2011 00:17:22 +0000 (02:17 +0200)
committerFrederic Weisbecker <fweisbec@gmail.com>
Sun, 22 May 2011 01:38:49 +0000 (03:38 +0200)
Better handle event parsing error by propagating the details
in upper layers or by dumping some failure message. So that
the user knows he has some crazy events in the batch.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
tools/perf/builtin-test.c
tools/perf/builtin-top.c
tools/perf/util/python.c
tools/perf/util/session.c

index 44d7df2804301f645e36d34f67bf9406aab35d90..1fa9f58c2af224d8b23efc669b867752e4da3f08 100644 (file)
@@ -559,8 +559,13 @@ static int test__basic_mmap(void)
                        goto out_munmap;
                }
 
-               perf_event__parse_sample(event, attr.sample_type, sample_size,
-                                        false, &sample);
+               err = perf_event__parse_sample(event, attr.sample_type, sample_size,
+                                              false, &sample);
+               if (err) {
+                       pr_err("Can't parse sample, err = %d\n", err);
+                       goto out_munmap;
+               }
+
                evsel = perf_evlist__id2evsel(evlist, sample.id);
                if (evsel == NULL) {
                        pr_debug("event with id %" PRIu64
index 7e3d6e310bf839f09e5d6afed39c8c1530a13807..74f533cbf6cafbaed250dc94801156a419f17398 100644 (file)
@@ -805,9 +805,14 @@ static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu)
 {
        struct perf_sample sample;
        union perf_event *event;
+       int ret;
 
        while ((event = perf_evlist__read_on_cpu(top.evlist, cpu)) != NULL) {
-               perf_session__parse_sample(self, event, &sample);
+               ret = perf_session__parse_sample(self, event, &sample);
+               if (ret) {
+                       pr_err("Can't parse sample, err = %d\n", ret);
+                       continue;
+               }
 
                if (event->header.type == PERF_RECORD_SAMPLE)
                        perf_event__process_sample(event, &sample, self);
index 4174c0990320b21ab0506fa3cfd37c5519a8057d..3344d6e6f048bdaf8401b5ee0b90dd32fe41b51e 100644 (file)
@@ -675,6 +675,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
        union perf_event *event;
        int sample_id_all = 1, cpu;
        static char *kwlist[] = {"sample_id_all", NULL, NULL};
+       int err;
 
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
                                         &cpu, &sample_id_all))
@@ -690,12 +691,17 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
                        return PyErr_NoMemory();
 
                first = list_entry(evlist->entries.next, struct perf_evsel, node);
-               perf_event__parse_sample(event, first->attr.sample_type,
-                                        perf_sample_size(first->attr.sample_type),
-                                        sample_id_all, &pevent->sample);
+               err = perf_event__parse_sample(event, first->attr.sample_type,
+                                              perf_sample_size(first->attr.sample_type),
+                                              sample_id_all, &pevent->sample);
+               if (err) {
+                       pr_err("Can't parse sample, err = %d\n", err);
+                       goto end;
+               }
+
                return pyevent;
        }
-
+end:
        Py_INCREF(Py_None);
        return Py_None;
 }
index 8940fd871eae106f8e08bfc649e792934206d0a4..948327d9e92b6b19dc0264e9d66e8827d0be3d4b 100644 (file)
@@ -480,6 +480,7 @@ static void flush_sample_queue(struct perf_session *s,
        struct perf_sample sample;
        u64 limit = os->next_flush;
        u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
+       int ret;
 
        if (!ops->ordered_samples || !limit)
                return;
@@ -488,9 +489,12 @@ static void flush_sample_queue(struct perf_session *s,
                if (iter->timestamp > limit)
                        break;
 
-               perf_session__parse_sample(s, iter->event, &sample);
-               perf_session_deliver_event(s, iter->event, &sample, ops,
-                                          iter->file_offset);
+               ret = perf_session__parse_sample(s, iter->event, &sample);
+               if (ret)
+                       pr_err("Can't parse sample, err = %d\n", ret);
+               else
+                       perf_session_deliver_event(s, iter->event, &sample, ops,
+                                                  iter->file_offset);
 
                os->last_flush = iter->timestamp;
                list_del(&iter->list);
@@ -806,7 +810,9 @@ static int perf_session__process_event(struct perf_session *session,
        /*
         * For all kernel events we get the sample data
         */
-       perf_session__parse_sample(session, event, &sample);
+       ret = perf_session__parse_sample(session, event, &sample);
+       if (ret)
+               return ret;
 
        /* Preprocess sample records - precheck callchains */
        if (perf_session__preprocess_sample(session, event, &sample))