On Thu, Oct 5, 2023 at 4:09 PM Ian Rogers <irogers@xxxxxxxxxx> wrote: > > Memory leaks were detected by clang-tidy. > > Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx> > --- > tools/perf/util/header.c | 63 ++++++++++++++++++++++++---------------- > 1 file changed, 38 insertions(+), 25 deletions(-) > > diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c > index d812e1e371a7..41b78e40b22b 100644 > --- a/tools/perf/util/header.c > +++ b/tools/perf/util/header.c > @@ -2598,8 +2598,10 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) > goto error; > > /* include a NULL character at the end */ > - if (strbuf_add(&sb, str, strlen(str) + 1) < 0) > + if (strbuf_add(&sb, str, strlen(str) + 1) < 0) { > + free(str); > goto error; > + } > size += string_size(str); > free(str); > } > @@ -2617,8 +2619,10 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) > goto error; > > /* include a NULL character at the end */ > - if (strbuf_add(&sb, str, strlen(str) + 1) < 0) > + if (strbuf_add(&sb, str, strlen(str) + 1) < 0) { > + free(str); > goto error; > + } > size += string_size(str); > free(str); > } > @@ -2681,8 +2685,10 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) > goto error; > > /* include a NULL character at the end */ > - if (strbuf_add(&sb, str, strlen(str) + 1) < 0) > + if (strbuf_add(&sb, str, strlen(str) + 1) < 0) { > + free(str); > goto error; > + } > size += string_size(str); > free(str); > } For these cases, it'd be simpler to free it in the error path. > @@ -2736,10 +2742,9 @@ static int process_numa_topology(struct feat_fd *ff, void *data __maybe_unused) > goto error; > > n->map = perf_cpu_map__new(str); > + free(str); > if (!n->map) > goto error; > - > - free(str); > } > ff->ph->env.nr_numa_nodes = nr; > ff->ph->env.numa_nodes = nodes; > @@ -2913,10 +2918,10 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused) > return -1; > > for (i = 0; i < cnt; i++) { > - struct cpu_cache_level c; > + struct cpu_cache_level *c = &caches[i]; > > #define _R(v) \ > - if (do_read_u32(ff, &c.v))\ > + if (do_read_u32(ff, &c->v)) \ > goto out_free_caches; \ > > _R(level) > @@ -2926,22 +2931,25 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused) > #undef _R > > #define _R(v) \ > - c.v = do_read_string(ff); \ > - if (!c.v) \ > - goto out_free_caches; > + c->v = do_read_string(ff); \ > + if (!c->v) \ > + goto out_free_caches; \ > > _R(type) > _R(size) > _R(map) > #undef _R > - > - caches[i] = c; > } > > ff->ph->env.caches = caches; > ff->ph->env.caches_cnt = cnt; > return 0; > out_free_caches: > + for (i = 0; i < cnt; i++) { > + free(caches[i].type); > + free(caches[i].size); > + free(caches[i].map); > + } > free(caches); > return -1; > } Looks ok. > @@ -3585,18 +3593,16 @@ static int perf_header__adds_write(struct perf_header *header, > struct feat_copier *fc) > { > int nr_sections; > - struct feat_fd ff; > + struct feat_fd ff = { > + .fd = fd, > + .ph = header, > + }; I'm fine with this change. > struct perf_file_section *feat_sec, *p; > int sec_size; > u64 sec_start; > int feat; > int err; > > - ff = (struct feat_fd){ > - .fd = fd, > - .ph = header, > - }; > - > nr_sections = bitmap_weight(header->adds_features, HEADER_FEAT_BITS); > if (!nr_sections) > return 0; > @@ -3623,6 +3629,7 @@ static int perf_header__adds_write(struct perf_header *header, > err = do_write(&ff, feat_sec, sec_size); > if (err < 0) > pr_debug("failed to write feature section\n"); > + free(ff.buf); But it looks like false alarams. Since the feat_fd has fd and no buf, it won't allocate the buffer in do_write() and just use __do_write_fd(). So no need to free the buf. Thanks, Namhyung > free(feat_sec); > return err; > } > @@ -3630,11 +3637,11 @@ static int perf_header__adds_write(struct perf_header *header, > int perf_header__write_pipe(int fd) > { > struct perf_pipe_file_header f_header; > - struct feat_fd ff; > + struct feat_fd ff = { > + .fd = fd, > + }; > int err; > > - ff = (struct feat_fd){ .fd = fd }; > - > f_header = (struct perf_pipe_file_header){ > .magic = PERF_MAGIC, > .size = sizeof(f_header), > @@ -3645,7 +3652,7 @@ int perf_header__write_pipe(int fd) > pr_debug("failed to write perf pipe header\n"); > return err; > } > - > + free(ff.buf); > return 0; > } > > @@ -3658,11 +3665,12 @@ static int perf_session__do_write_header(struct perf_session *session, > struct perf_file_attr f_attr; > struct perf_header *header = &session->header; > struct evsel *evsel; > - struct feat_fd ff; > + struct feat_fd ff = { > + .fd = fd, > + }; > u64 attr_offset; > int err; > > - ff = (struct feat_fd){ .fd = fd}; > lseek(fd, sizeof(f_header), SEEK_SET); > > evlist__for_each_entry(session->evlist, evsel) { > @@ -3670,6 +3678,7 @@ static int perf_session__do_write_header(struct perf_session *session, > err = do_write(&ff, evsel->core.id, evsel->core.ids * sizeof(u64)); > if (err < 0) { > pr_debug("failed to write perf header\n"); > + free(ff.buf); > return err; > } > } > @@ -3695,6 +3704,7 @@ static int perf_session__do_write_header(struct perf_session *session, > err = do_write(&ff, &f_attr, sizeof(f_attr)); > if (err < 0) { > pr_debug("failed to write perf header attribute\n"); > + free(ff.buf); > return err; > } > } > @@ -3705,8 +3715,10 @@ static int perf_session__do_write_header(struct perf_session *session, > > if (at_exit) { > err = perf_header__adds_write(header, evlist, fd, fc); > - if (err < 0) > + if (err < 0) { > + free(ff.buf); > return err; > + } > } > > f_header = (struct perf_file_header){ > @@ -3728,6 +3740,7 @@ static int perf_session__do_write_header(struct perf_session *session, > > lseek(fd, 0, SEEK_SET); > err = do_write(&ff, &f_header, sizeof(f_header)); > + free(ff.buf); > if (err < 0) { > pr_debug("failed to write perf header\n"); > return err; > -- > 2.42.0.609.gbb76f46606-goog >