[PATCH 1/3] libtracefs utest: Add test to check handling multiple dynamic events

Steven Rostedt <[email protected]>
Newsgroups org.kernel.vger.linux-trace-devel
Message-ID <[email protected]>
From: "Steven Rostedt (Google)" <[email protected]>

Add a new "mutli probes" test that will create kprobes, kretprobes,
uprobes, uretprobes, eprobes and synthetic events and make sure that the
counters of those events are working properly.

Signed-off-by: Steven Rostedt (Google) <[email protected]>
---
 utest/tracefs-utest.c | 162 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 162 insertions(+)

diff --git a/utest/tracefs-utest.c b/utest/tracefs-utest.c
index 5bfd665b9990..742f4546bef0 100644
--- a/utest/tracefs-utest.c
+++ b/utest/tracefs-utest.c
@@ -2574,6 +2574,167 @@ static void test_uprobes(void)
 	test_uprobes_instance(test_instance);
 }
 
+static void test_multi_probes_instance(struct tracefs_instance *instance)
+{
+	struct probe_test tests[] = {
+		{ TRACEFS_DYNEVENT_UPROBE, "p", "utest", "utest_u", NULL, "arg1=$stack2" },
+		{ TRACEFS_DYNEVENT_URETPROBE, "r", "utest", "utest_r", NULL, "arg1=$retval" },
+		{ TRACEFS_DYNEVENT_EPROBE, "e", NULL, "sopen_in", "syscalls.sys_enter_openat",
+					   "file=+0($filename):ustring" },
+		{ TRACEFS_DYNEVENT_EPROBE, "e", "etest", "sopen_out", "syscalls.sys_exit_openat",
+					   "res=$ret:u64" },
+		{ TRACEFS_DYNEVENT_KPROBE, "p", NULL, "mkdir", "do_mkdirat", "path=+u0($arg2):ustring" },
+		{ TRACEFS_DYNEVENT_KPROBE, "p", NULL, "close", "close_fd", NULL },
+		{ TRACEFS_DYNEVENT_KPROBE, "p", "ptest", "open2", "do_sys_openat2",
+				  "file=+u0($arg2):ustring flags=+0($arg3):x64" },
+		{ TRACEFS_DYNEVENT_KRETPROBE, NULL, NULL, "retopen", "do_sys_openat2", "ret=$retval" },
+		{ TRACEFS_DYNEVENT_KRETPROBE, NULL, NULL, NULL, "do_sys_open", "ret=$retval" },
+	};
+	struct test_synth sevents[] = {
+		{"synth_1", "sched", "sched_waking", "sched", "sched_switch", "pid", "next_pid", "pid_match"},
+		{"synth_2", "syscalls", "sys_enter_openat2", "syscalls", "sys_exit_openat2", "__syscall_nr", "__syscall_nr", "nr_match"},
+	};
+	int sevents_count = sizeof(sevents) / sizeof((sevents)[0]);
+	int count = sizeof(tests) / sizeof((tests)[0]);
+	struct tracefs_dynevent **probes;
+	struct tracefs_synth **synth;
+	struct tep_handle *tep;
+	char self[PATH_MAX] = { 0 };
+	char *target = NULL;
+	char *tsys, *tevent;
+	char *tmp, *sav;
+	/* The below matches the tests and sevents arrays */
+	const int uprobes_cnt = 1;
+	const int uretprobes_cnt = 1;
+	const int eprobes_cnt = 2;
+	const int kprobes_cnt = 3;
+	const int kretprobes_cnt = 2;
+	int ret;
+	int i;
+
+	synth = calloc(sevents_count + 1, sizeof(*synth));
+
+	tep = tracefs_local_events(NULL);
+	CU_TEST(tep != NULL);
+
+	destroy_dynevents(TRACEFS_DYNEVENT_ALL);
+
+	for (i = 0; i < sevents_count; i++) {
+		synth[i] = tracefs_synth_alloc(tep,  sevents[i].name,
+					       sevents[i].start_system, sevents[i].start_event,
+					       sevents[i].end_system, sevents[i].end_event,
+					       sevents[i].start_match_field, sevents[i].end_match_field,
+					       sevents[i].match_name);
+		CU_TEST(synth[i] != NULL);
+	}
+
+	probes = calloc(count + 1, sizeof(*probes));
+	CU_TEST(probes != NULL);
+	CU_TEST(readlink("/proc/self/exe", self, sizeof(self)) > 0);
+	CU_TEST(asprintf(&target, "%s:0x%0*llx", self, (int)(sizeof(void *) * 2), FOFFSET) > 0);
+
+	for (i = 0; i < count; i++) {
+		switch (tests[i].type) {
+		case TRACEFS_DYNEVENT_UPROBE:
+			tests[i].address = target;
+			probes[i] = tracefs_uprobe_alloc(tests[i].system, tests[i].event,
+							   self, FOFFSET, tests[i].format);
+			break;
+		case TRACEFS_DYNEVENT_URETPROBE:
+			tests[i].address = target;
+			probes[i] = tracefs_uretprobe_alloc(tests[i].system, tests[i].event,
+							      self, FOFFSET, tests[i].format);
+			break;
+		case TRACEFS_DYNEVENT_KPROBE:
+			probes[i] = tracefs_kprobe_alloc(tests[i].system, tests[i].event,
+						  tests[i].address, tests[i].format);
+			break;
+		case TRACEFS_DYNEVENT_KRETPROBE:
+			probes[i] = tracefs_kretprobe_alloc(tests[i].system, tests[i].event,
+							    tests[i].address, tests[i].format, 0);
+			break;
+		case TRACEFS_DYNEVENT_EPROBE:
+			tmp = strdup(tests[i].address);
+			tsys = strtok_r(tmp, "./", &sav);
+			tevent = strtok_r(NULL, "", &sav);
+			probes[i] = tracefs_eprobe_alloc(tests[i].system, tests[i].event,
+							   tsys, tevent, tests[i].format);
+			free(tmp);
+			break;
+		default:
+			CU_TEST(0);
+			break;
+		}
+
+		CU_TEST(probes[i] != NULL);
+	}
+	probes[i] = NULL;
+
+	get_dynevents_check(TRACEFS_DYNEVENT_ALL, 0);
+	CU_TEST(check_probes(tests, count, probes, false, instance, tep));
+
+	for (i = 0; i < count; i++) {
+		CU_TEST(tracefs_dynevent_create(probes[i]) == 0);
+	}
+
+	get_dynevents_check(TRACEFS_DYNEVENT_ALL, count);
+
+	for (i = 0; i < sevents_count; i++) {
+		CU_TEST(tracefs_synth_create(synth[i]) == 0);
+	}
+
+	get_dynevents_check(TRACEFS_DYNEVENT_ALL, count + sevents_count);
+
+	CU_TEST(check_probes(tests, count, probes, true, instance, tep));
+
+	get_dynevents_check(TRACEFS_DYNEVENT_UPROBE, uprobes_cnt);
+	get_dynevents_check(TRACEFS_DYNEVENT_URETPROBE, uretprobes_cnt);
+	get_dynevents_check(TRACEFS_DYNEVENT_UPROBE |
+			    TRACEFS_DYNEVENT_URETPROBE, uprobes_cnt + uretprobes_cnt);
+
+	get_dynevents_check(TRACEFS_DYNEVENT_KPROBE, kprobes_cnt);
+	get_dynevents_check(TRACEFS_DYNEVENT_KRETPROBE, kretprobes_cnt);
+	get_dynevents_check(TRACEFS_DYNEVENT_KPROBE |
+			    TRACEFS_DYNEVENT_KRETPROBE, kprobes_cnt + kretprobes_cnt);
+
+	get_dynevents_check(TRACEFS_DYNEVENT_EPROBE, eprobes_cnt);
+
+	get_dynevents_check(TRACEFS_DYNEVENT_SYNTH, sevents_count);
+
+	get_dynevents_check(TRACEFS_DYNEVENT_EPROBE | TRACEFS_DYNEVENT_SYNTH,
+			    eprobes_cnt + sevents_count);
+
+
+	for (i = 0; i < count; i++) {
+		CU_TEST(tracefs_dynevent_destroy(probes[i], false) == 0);
+	}
+
+	get_dynevents_check(TRACEFS_DYNEVENT_ALL, sevents_count);
+
+	for (i = 0; i < sevents_count; i++) {
+		ret = tracefs_synth_destroy(synth[i]);
+		CU_TEST(ret == 0);
+	}
+
+	get_dynevents_check(TRACEFS_DYNEVENT_ALL, 0);
+
+	for (i = 0; i < count; i++)
+		tracefs_dynevent_free(probes[i]);
+
+	for (i = 0; i < sevents_count; i++)
+		tracefs_synth_free(synth[i]);
+
+	free(synth);
+	free(probes);
+	free(target);
+	tep_free(tep);
+}
+
+static void test_multi_probes(void)
+{
+	test_multi_probes_instance(test_instance);
+}
+
 static void test_instance_file(void)
 {
 	struct tracefs_instance *instance = NULL;
@@ -3693,4 +3854,5 @@ void test_tracefs_lib(void)
 	CU_add_test(suite, "synthetic events", test_synthetic);
 	CU_add_test(suite, "eprobes", test_eprobes);
 	CU_add_test(suite, "uprobes", test_uprobes);
+	CU_add_test(suite, "multi probe test", test_multi_probes);
 }
-- 
2.45.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.