perf metric: Fix some memory leaks
authorNamhyung Kim <namhyung@kernel.org>
Tue, 15 Sep 2020 03:18:09 +0000 (12:18 +0900)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 15 Sep 2020 11:58:03 +0000 (08:58 -0300)
I found some memory leaks while reading the metric code.  Some are real
and others only occur in the error path.  When it failed during metric
or event parsing, it should release all resources properly.

Fixes: b18f3e365019d ("perf stat: Support JSON metrics in perf stat")
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lore.kernel.org/lkml/20200915031819.386559-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/metricgroup.c

index 8831b964288fa59c125fc3b085fdbc3da7eb3535..af664d6218d64a1fcee04ddc394e2b3594ea37fd 100644 (file)
@@ -530,6 +530,9 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter,
                                                continue;
                                        strlist__add(me->metrics, s);
                                }
+
+                               if (!raw)
+                                       free(s);
                        }
                        free(omg);
                }
@@ -1040,7 +1043,7 @@ static int parse_groups(struct evlist *perf_evlist, const char *str,
        ret = metricgroup__add_metric_list(str, metric_no_group,
                                           &extra_events, &metric_list, map);
        if (ret)
-               return ret;
+               goto out;
        pr_debug("adding %s\n", extra_events.buf);
        bzero(&parse_error, sizeof(parse_error));
        ret = __parse_events(perf_evlist, extra_events.buf, &parse_error, fake_pmu);
@@ -1048,11 +1051,11 @@ static int parse_groups(struct evlist *perf_evlist, const char *str,
                parse_events_print_error(&parse_error, extra_events.buf);
                goto out;
        }
-       strbuf_release(&extra_events);
        ret = metricgroup__setup_events(&metric_list, metric_no_merge,
                                        perf_evlist, metric_events);
 out:
        metricgroup__free_metrics(&metric_list);
+       strbuf_release(&extra_events);
        return ret;
 }