summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2026-06-13 19:46:29 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2026-06-17 15:21:03 +0300
commit8a4506595857356fcef9f7aad3506593e9fabbbc (patch)
treecd7ada019754c171d0d331d101bb2f340f778424
parentd669529868b355e1f10ff869539dc995cd25db3f (diff)
downloadlinux-8a4506595857356fcef9f7aad3506593e9fabbbc.tar.xz
perf machine: Propagate machine__init() error to callers
machine__init() always returns 0 even when memory allocation fails, because commit 81f981d7ec43ed93 ("perf machine: Free root_dir in machine__init() error path") introduced 'int err = -ENOMEM' and an error cleanup path but left the final 'return 0' instead of 'return err'. Fix by returning err, check the return value in __machine__new_host() which was ignoring it, and change machines__init() from void to int so it too can propagate the error to perf_session__new(), aslr_tool__init() and test callers. The error cleanup also used zfree(&machine->kmaps), but kmaps is a refcounted maps structure — use maps__zput() to properly drop the reference, matching machine__exit(). Move dsos__init() and threads__init() before the first fallible allocation (maps__new) so that machine__exit() is safe to call on any machine struct that machine__init() touched, even on early failure. Fixes: 81f981d7ec43ed93 ("perf machine: Free root_dir in machine__init() error path") Reported-by: sashiko-bot <sashiko-bot@kernel.org> Cc: Ian Rogers <irogers@google.com> Cc: Jiri Olsa <jolsa@kernel.org> Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/tests/hists_cumulate.c5
-rw-r--r--tools/perf/tests/hists_filter.c5
-rw-r--r--tools/perf/tests/hists_link.c5
-rw-r--r--tools/perf/tests/hists_output.c5
-rw-r--r--tools/perf/tests/kallsyms-split.c7
-rw-r--r--tools/perf/tests/thread-maps-share.c2
-rw-r--r--tools/perf/tests/vmlinux-kallsyms.c8
-rw-r--r--tools/perf/util/aslr.c12
-rw-r--r--tools/perf/util/machine.c24
-rw-r--r--tools/perf/util/machine.h2
-rw-r--r--tools/perf/util/session.c7
11 files changed, 51 insertions, 31 deletions
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c
index 267cbc24691a..09ee08085b06 100644
--- a/tools/perf/tests/hists_cumulate.c
+++ b/tools/perf/tests/hists_cumulate.c
@@ -704,7 +704,7 @@ out:
static int test__hists_cumulate(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
int err = TEST_FAIL;
- struct machines machines;
+ struct machines machines = { 0 };
struct machine *machine;
struct evsel *evsel;
struct evlist *evlist = evlist__new();
@@ -723,7 +723,8 @@ static int test__hists_cumulate(struct test_suite *test __maybe_unused, int subt
goto out;
err = TEST_FAIL;
- machines__init(&machines);
+ if (machines__init(&machines))
+ goto out;
/* setup threads/dso/map/symbols also */
machine = setup_fake_machine(&machines);
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c
index 002e3a4c1ca5..ac5affb7afff 100644
--- a/tools/perf/tests/hists_filter.c
+++ b/tools/perf/tests/hists_filter.c
@@ -116,7 +116,7 @@ static void put_fake_samples(void)
static int test__hists_filter(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
int err = TEST_FAIL;
- struct machines machines;
+ struct machines machines = { 0 };
struct machine *machine;
struct evsel *evsel;
struct evlist *evlist = evlist__new();
@@ -131,7 +131,8 @@ static int test__hists_filter(struct test_suite *test __maybe_unused, int subtes
goto out;
err = TEST_FAIL;
- machines__init(&machines);
+ if (machines__init(&machines))
+ goto out;
/* setup threads/dso/map/symbols also */
machine = setup_fake_machine(&machines);
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 996f5f0b3bd1..e55990163865 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -287,7 +287,7 @@ static int test__hists_link(struct test_suite *test __maybe_unused, int subtest
{
int err = -1;
struct hists *hists, *first_hists;
- struct machines machines;
+ struct machines machines = { 0 };
struct machine *machine = NULL;
struct evsel *evsel, *first;
struct evlist *evlist = evlist__new();
@@ -303,7 +303,8 @@ static int test__hists_link(struct test_suite *test __maybe_unused, int subtest
goto out;
err = TEST_FAIL;
- machines__init(&machines);
+ if (machines__init(&machines))
+ goto out;
/* setup threads/dso/map/symbols also */
machine = setup_fake_machine(&machines);
diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c
index fa683fd7b1e5..5e59dba92e81 100644
--- a/tools/perf/tests/hists_output.c
+++ b/tools/perf/tests/hists_output.c
@@ -590,7 +590,7 @@ out:
static int test__hists_output(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
int err = TEST_FAIL;
- struct machines machines;
+ struct machines machines = { 0 };
struct machine *machine;
struct evsel *evsel;
struct evlist *evlist = evlist__new();
@@ -610,7 +610,8 @@ static int test__hists_output(struct test_suite *test __maybe_unused, int subtes
goto out;
err = TEST_FAIL;
- machines__init(&machines);
+ if (machines__init(&machines))
+ goto out;
/* setup threads/dso/map/symbols also */
machine = setup_fake_machine(&machines);
diff --git a/tools/perf/tests/kallsyms-split.c b/tools/perf/tests/kallsyms-split.c
index 117ed3b70f63..244daa01bd5d 100644
--- a/tools/perf/tests/kallsyms-split.c
+++ b/tools/perf/tests/kallsyms-split.c
@@ -97,7 +97,7 @@ err:
static int test__kallsyms_split(struct test_suite *test __maybe_unused,
int subtest __maybe_unused)
{
- struct machine m;
+ struct machine m = { 0 };
struct map *map = NULL;
int ret = TEST_FAIL;
@@ -113,7 +113,10 @@ static int test__kallsyms_split(struct test_suite *test __maybe_unused,
signal(SIGTERM, remove_proc_dir);
pr_debug("create kernel maps from the fake root directory\n");
- machine__init(&m, root_dir, HOST_KERNEL_ID);
+ if (machine__init(&m, root_dir, HOST_KERNEL_ID)) {
+ pr_debug("FAIL: failed to init machine\n");
+ goto out;
+ }
if (machine__create_kernel_maps(&m) < 0) {
pr_debug("FAIL: failed to create kernel maps\n");
goto out;
diff --git a/tools/perf/tests/thread-maps-share.c b/tools/perf/tests/thread-maps-share.c
index e9ecd30a5c05..0431bff31b3a 100644
--- a/tools/perf/tests/thread-maps-share.c
+++ b/tools/perf/tests/thread-maps-share.c
@@ -27,7 +27,7 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s
* other group (pid: 4, tids: 4, 5)
*/
- machines__init(&machines);
+ TEST_ASSERT_VAL("failed to init machines", machines__init(&machines) == 0);
machine = &machines.host;
/* create process with 4 threads */
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c
index 7409abe4aa36..9396c8a77c86 100644
--- a/tools/perf/tests/vmlinux-kallsyms.c
+++ b/tools/perf/tests/vmlinux-kallsyms.c
@@ -192,7 +192,7 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
struct rb_node *nd;
struct symbol *sym;
struct map *kallsyms_map;
- struct machine vmlinux;
+ struct machine vmlinux = { 0 };
struct maps *maps;
u64 mem_start, mem_end;
struct test__vmlinux_matches_kallsyms_cb_args args;
@@ -203,8 +203,10 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
* Init the machines that will hold kernel, modules obtained from
* both vmlinux + .ko files and from /proc/kallsyms split by modules.
*/
- machine__init(&args.kallsyms, "", HOST_KERNEL_ID);
- machine__init(&vmlinux, "", HOST_KERNEL_ID);
+ if (machine__init(&args.kallsyms, "", HOST_KERNEL_ID))
+ goto out;
+ if (machine__init(&vmlinux, "", HOST_KERNEL_ID))
+ goto out;
maps = machine__kernel_maps(&vmlinux);
diff --git a/tools/perf/util/aslr.c b/tools/perf/util/aslr.c
index a946fff2ac4d..6a7542e7db82 100644
--- a/tools/perf/util/aslr.c
+++ b/tools/perf/util/aslr.c
@@ -1237,12 +1237,13 @@ void aslr_tool__strip_attr_event(union perf_event *event, struct evlist *evlist)
}
}
-static void aslr_tool__init(struct aslr_tool *aslr, struct perf_tool *delegate)
+static int aslr_tool__init(struct aslr_tool *aslr, struct perf_tool *delegate)
{
delegate_tool__init(&aslr->tool, delegate);
aslr->tool.tool.ordered_events = true;
- machines__init(&aslr->machines);
+ if (machines__init(&aslr->machines))
+ return -ENOMEM;
hashmap__init(&aslr->remap_addresses,
remap_addresses__hash, remap_addresses__equal,
@@ -1276,6 +1277,8 @@ static void aslr_tool__init(struct aslr_tool *aslr, struct perf_tool *delegate)
aslr->tool.tool.auxtrace = aslr_tool__process_auxtrace;
aslr->tool.tool.auxtrace_info = aslr_tool__process_auxtrace_info;
aslr->tool.tool.auxtrace_error = aslr_tool__process_auxtrace_error;
+
+ return 0;
}
struct perf_tool *aslr_tool__new(struct perf_tool *delegate)
@@ -1285,7 +1288,10 @@ struct perf_tool *aslr_tool__new(struct perf_tool *delegate)
if (!aslr)
return NULL;
- aslr_tool__init(aslr, delegate);
+ if (aslr_tool__init(aslr, delegate)) {
+ free(aslr);
+ return NULL;
+ }
return &aslr->tool.tool;
}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 31715366e29f..9329d319bd03 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -79,15 +79,14 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
int err = -ENOMEM;
memset(machine, 0, sizeof(*machine));
- machine->kmaps = maps__new(machine);
- if (machine->kmaps == NULL)
- return -ENOMEM;
-
RB_CLEAR_NODE(&machine->rb_node);
dsos__init(&machine->dsos);
-
threads__init(&machine->threads);
+ machine->kmaps = maps__new(machine);
+ if (machine->kmaps == NULL)
+ goto out;
+
machine->vdso_info = NULL;
machine->env = NULL;
@@ -124,11 +123,11 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
out:
if (err) {
- zfree(&machine->kmaps);
+ maps__zput(machine->kmaps);
zfree(&machine->root_dir);
zfree(&machine->mmap_name);
}
- return 0;
+ return err;
}
static struct machine *__machine__new_host(struct perf_env *host_env, bool kernel_maps)
@@ -138,7 +137,10 @@ static struct machine *__machine__new_host(struct perf_env *host_env, bool kerne
if (!machine)
return NULL;
- machine__init(machine, "", HOST_KERNEL_ID);
+ if (machine__init(machine, "", HOST_KERNEL_ID) != 0) {
+ free(machine);
+ return NULL;
+ }
if (kernel_maps && machine__create_kernel_maps(machine) < 0) {
free(machine);
@@ -231,10 +233,12 @@ void machine__delete(struct machine *machine)
}
}
-void machines__init(struct machines *machines)
+int machines__init(struct machines *machines)
{
- machine__init(&machines->host, "", HOST_KERNEL_ID);
+ int err = machine__init(&machines->host, "", HOST_KERNEL_ID);
+
machines->guests = RB_ROOT_CACHED;
+ return err;
}
void machines__exit(struct machines *machines)
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index aaddfb70ea66..26f9827062f5 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -152,7 +152,7 @@ struct machines {
struct rb_root_cached guests;
};
-void machines__init(struct machines *machines);
+int machines__init(struct machines *machines);
void machines__exit(struct machines *machines);
void machines__process_guests(struct machines *machines,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 1a9a008ddda3..f391a822480d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -160,11 +160,12 @@ struct perf_session *__perf_session__new(struct perf_data *data,
session->decomp_data.zstd_decomp = &session->zstd_data;
session->active_decomp = &session->decomp_data;
INIT_LIST_HEAD(&session->auxtrace_index);
- machines__init(&session->machines);
+ perf_env__init(&session->header.env);
+ if (machines__init(&session->machines))
+ goto out_delete;
+
ordered_events__init(&session->ordered_events,
ordered_events__deliver_event, NULL);
-
- perf_env__init(&session->header.env);
if (data) {
ret = perf_data__open(data);
if (ret < 0)