]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
perf machine: Propagate machine__init() error to callers
authorArnaldo Carvalho de Melo <acme@redhat.com>
Sat, 13 Jun 2026 16:46:29 +0000 (13:46 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 17 Jun 2026 12:21:03 +0000 (09:21 -0300)
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>
tools/perf/tests/hists_cumulate.c
tools/perf/tests/hists_filter.c
tools/perf/tests/hists_link.c
tools/perf/tests/hists_output.c
tools/perf/tests/kallsyms-split.c
tools/perf/tests/thread-maps-share.c
tools/perf/tests/vmlinux-kallsyms.c
tools/perf/util/aslr.c
tools/perf/util/machine.c
tools/perf/util/machine.h
tools/perf/util/session.c

index 267cbc24691acd77aa94dbaa2b83be702acf512b..09ee08085b06b14f3d02b156253a18bca0c6ba32 100644 (file)
@@ -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);
index 002e3a4c1ca59b9d48a5047fe54c0f7a351bd6ea..ac5affb7afff11beec0bb3c4c8c7ec8285923ef7 100644 (file)
@@ -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);
index 996f5f0b3bd17fe5a18263273d65c218af191c4d..e55990163865e66fce411cbe36733ffcc68d3120 100644 (file)
@@ -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);
index fa683fd7b1e5ebb2b8dcbec054abdae603135100..5e59dba92e8132a3d88c107b1b3d3cb8e98784ae 100644 (file)
@@ -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);
index 117ed3b70f630a9788f411411e3d61c3233084ab..244daa01bd5d85fbebc8cd10f7bad3ed1b16c41e 100644 (file)
@@ -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;
index e9ecd30a5c058076b9eb8f1aa4f5950e3663cbea..0431bff31b3a18c3eebd54d8635d086caf8d0b5e 100644 (file)
@@ -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 */
index 7409abe4aa3692ea1a68ed63827b24f84be9a601..9396c8a77c863718048e1f55d5c505990fabfc5b 100644 (file)
@@ -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);
 
index a946fff2ac4dd4b45249f4c5c4d97b17830a60fd..6a7542e7db827d1b7d60160a0d8c8fd54485cc40 100644 (file)
@@ -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;
 }
 
index 31715366e29ff704ff73c08e1a680863d81c48bc..9329d319bd0336991659c2ae93ab6747707444ee 100644 (file)
@@ -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)
index aaddfb70ea6654525e928769b7d621a6ae59c3a7..26f9827062f5eb5b61b04fbe97430e10ef3c6a3a 100644 (file)
@@ -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,
index 1a9a008ddda35120818b7f0de03845040ef610c0..f391a822480db00145ac1ebc673f9010679ff2b4 100644 (file)
@@ -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)