Commit 10525450 authored by Ian Rogers's avatar Ian Rogers Committed by Namhyung Kim
Browse files

perf header: Fix various error path memory leaks



Memory leaks were detected by clang-tidy.

Signed-off-by: default avatarIan Rogers <irogers@google.com>
Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: llvm@lists.linux.dev
Cc: Ming Wang <wangming01@loongson.cn>
Cc: Tom Rix <trix@redhat.com>
Cc: bpf@vger.kernel.org
Link: https://lore.kernel.org/r/20231009183920.200859-19-irogers@google.com


Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
parent 97fe0383
Loading
Loading
Loading
Loading
+34 −26
Original line number Diff line number Diff line
@@ -2573,7 +2573,7 @@ static int process_cmdline(struct feat_fd *ff, void *data __maybe_unused)
static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
{
	u32 nr, i;
	char *str;
	char *str = NULL;
	struct strbuf sb;
	int cpu_nr = ff->ph->env.nr_cpus_avail;
	u64 size = 0;
@@ -2601,7 +2601,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
		if (strbuf_add(&sb, str, strlen(str) + 1) < 0)
			goto error;
		size += string_size(str);
		free(str);
		zfree(&str);
	}
	ph->env.sibling_cores = strbuf_detach(&sb, NULL);

@@ -2620,7 +2620,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
		if (strbuf_add(&sb, str, strlen(str) + 1) < 0)
			goto error;
		size += string_size(str);
		free(str);
		zfree(&str);
	}
	ph->env.sibling_threads = strbuf_detach(&sb, NULL);

@@ -2684,7 +2684,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)
		if (strbuf_add(&sb, str, strlen(str) + 1) < 0)
			goto error;
		size += string_size(str);
		free(str);
		zfree(&str);
	}
	ph->env.sibling_dies = strbuf_detach(&sb, NULL);

@@ -2699,6 +2699,7 @@ static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused)

error:
	strbuf_release(&sb);
	zfree(&str);
free_cpu:
	zfree(&ph->env.cpu);
	return -1;
@@ -2736,10 +2737,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 +2913,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 +2926,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;
}
@@ -3585,18 +3588,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,
	};
	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 +3624,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); /* TODO: added to silence clang-tidy. */
	free(feat_sec);
	return err;
}
@@ -3630,11 +3632,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 +3647,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 +3660,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 +3673,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 +3699,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,9 +3710,11 @@ 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){
		.magic	   = PERF_MAGIC,
@@ -3728,6 +3735,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;