[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260112132140.156956-1-costa.shul@redhat.com>
Date: Mon, 12 Jan 2026 15:21:28 +0200
From: Costa Shulyupin <costa.shul@...hat.com>
To: Steven Rostedt <rostedt@...dmis.org>,
Tomas Glozar <tglozar@...hat.com>,
Wander Lairson Costa <wander@...hat.com>,
Costa Shulyupin <costa.shul@...hat.com>,
Ivan Pravdin <ipravdin.official@...il.com>,
Tiezhu Yang <yangtiezhu@...ngson.cn>,
linux-kernel@...r.kernel.org,
linux-trace-kernel@...r.kernel.org
Subject: [PATCH v1] tools/rtla: Fix parse_cpu_set() and add unit test
The patch "Replace atoi() with a robust strtoi()" introduced a bug
in parse_cpu_set(), which relies on partial parsing of the input
string.
Restore the original use of atoi() in parse_cpu_set().
Add a unit test to prevent accidental regressions.
Fixes: 7e9dfccf8f11 ("rtla: Replace atoi() with a robust strtoi()")
Signed-off-by: Costa Shulyupin <costa.shul@...hat.com>
---
tools/tracing/rtla/Makefile | 3 ++
tools/tracing/rtla/src/utils.c | 10 ++--
tools/tracing/rtla/tests/Makefile | 12 +++++
tools/tracing/rtla/tests/test_utils.c | 74 +++++++++++++++++++++++++++
4 files changed, 93 insertions(+), 6 deletions(-)
create mode 100644 tools/tracing/rtla/tests/Makefile
create mode 100644 tools/tracing/rtla/tests/test_utils.c
diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile
index 2701256abaf3..1805916c7dba 100644
--- a/tools/tracing/rtla/Makefile
+++ b/tools/tracing/rtla/Makefile
@@ -109,7 +109,10 @@ clean: doc_clean fixdep-clean
$(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-*
$(Q)rm -rf feature
$(Q)rm -f src/timerlat.bpf.o src/timerlat.skel.h example/timerlat_bpf_action.o
+
check: $(RTLA) tests/bpf/bpf_action_map.o
+ make -C tests/ check
RTLA=$(RTLA) BPFTOOL=$(SYSTEM_BPFTOOL) prove -o -f -v tests/
+
examples: example/timerlat_bpf_action.o
.PHONY: FORCE clean check
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
index 18986a5aed3c..0da3b2470c31 100644
--- a/tools/tracing/rtla/src/utils.c
+++ b/tools/tracing/rtla/src/utils.c
@@ -128,18 +128,16 @@ int parse_cpu_set(char *cpu_list, cpu_set_t *set)
nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
for (p = cpu_list; *p; ) {
- if (strtoi(p, &cpu))
- goto err;
- if (cpu < 0 || cpu >= nr_cpus)
+ cpu = atoi(p);
+ if (cpu < 0 || (!cpu && *p != '0') || cpu >= nr_cpus)
goto err;
while (isdigit(*p))
p++;
if (*p == '-') {
p++;
- if (strtoi(p, &end_cpu))
- goto err;
- if (end_cpu < cpu || end_cpu >= nr_cpus)
+ end_cpu = atoi(p);
+ if (end_cpu < cpu || (!end_cpu && *p != '0') || end_cpu >= nr_cpus)
goto err;
while (isdigit(*p))
p++;
diff --git a/tools/tracing/rtla/tests/Makefile b/tools/tracing/rtla/tests/Makefile
new file mode 100644
index 000000000000..fe187306a404
--- /dev/null
+++ b/tools/tracing/rtla/tests/Makefile
@@ -0,0 +1,12 @@
+LIBS := -lcheck
+
+test_utils: test_utils.c ../src/utils.c
+ $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+
+check: test_utils
+ ./test_utils
+
+clean:
+ rm -f test_utils
+
+.PHONY: check clean
diff --git a/tools/tracing/rtla/tests/test_utils.c b/tools/tracing/rtla/tests/test_utils.c
new file mode 100644
index 000000000000..92ed49d60d33
--- /dev/null
+++ b/tools/tracing/rtla/tests/test_utils.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Unit tests for src/utils.c parsing functions
+ */
+
+#define _GNU_SOURCE
+#include <check.h>
+#include <unistd.h>
+
+#include "../src/utils.h"
+
+START_TEST(test_parse_cpu_set)
+{
+ cpu_set_t set;
+ int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+ ck_assert_int_eq(parse_cpu_set("0", &set), 0);
+ ck_assert(CPU_ISSET(0, &set));
+ ck_assert(!CPU_ISSET(1, &set));
+
+ if (nr_cpus > 2) {
+ ck_assert_int_eq(parse_cpu_set("0,2", &set), 0);
+ ck_assert(CPU_ISSET(0, &set));
+ ck_assert(CPU_ISSET(2, &set));
+ }
+
+ if (nr_cpus > 3) {
+ ck_assert_int_eq(parse_cpu_set("0-3", &set), 0);
+ ck_assert(CPU_ISSET(0, &set));
+ ck_assert(CPU_ISSET(1, &set));
+ ck_assert(CPU_ISSET(2, &set));
+ ck_assert(CPU_ISSET(3, &set));
+ }
+
+ if (nr_cpus > 5) {
+ ck_assert_int_eq(parse_cpu_set("1-3,5", &set), 0);
+ ck_assert(!CPU_ISSET(0, &set));
+ ck_assert(CPU_ISSET(1, &set));
+ ck_assert(CPU_ISSET(2, &set));
+ ck_assert(CPU_ISSET(3, &set));
+ ck_assert(!CPU_ISSET(4, &set));
+ ck_assert(CPU_ISSET(5, &set));
+ }
+
+ ck_assert_int_ne(parse_cpu_set("-1", &set), 0);
+ ck_assert_int_ne(parse_cpu_set("abc", &set), 0);
+ ck_assert_int_ne(parse_cpu_set("9999", &set), 0);
+}
+END_TEST
+
+Suite *utils_suite(void)
+{
+ Suite *s = suite_create("utils");
+ TCase *tc = tcase_create("core");
+
+ tcase_add_test(tc, test_parse_cpu_set);
+
+ suite_add_tcase(s, tc);
+ return s;
+}
+
+int main(void)
+{
+ int num_failed;
+ SRunner *sr;
+
+ sr = srunner_create(utils_suite());
+ srunner_run_all(sr, CK_NORMAL);
+ num_failed = srunner_ntests_failed(sr);
+
+ srunner_free(sr);
+
+ return (num_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
--
2.52.0
Powered by blists - more mailing lists