diff mbox series

trace-cmd utest: Add test cases for trace-cmd reset

Message ID 20241015140840.4183007-1-metin.kaya@arm.com (mailing list archive)
State Superseded
Headers show
Series trace-cmd utest: Add test cases for trace-cmd reset | expand

Commit Message

Metin Kaya Oct. 15, 2024, 2:08 p.m. UTC
Implement test cases to confirm existing dynamic event types (kprobe,
kretprobe, uprobe, uretprobe and eprobe) are really preserved during
"trace-cmd reset".

Verify synthetic events by inserting a hook to
test_trace_sqlhist_hist().

While we are in the neighborhood, fix typo "ceated".

TODO: I'm unable to prevent uprobes/uretprobes from being destroyed
during reset.

Link: https://lore.kernel.org/linux-trace-devel/20241014175905.03bec85a@gandalf.local.home

Signed-off-by: Metin Kaya <metin.kaya@arm.com>
---
 utest/tracecmd-utest.c | 161 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 160 insertions(+), 1 deletion(-)

Comments

Steven Rostedt Oct. 15, 2024, 4:38 p.m. UTC | #1
On Tue, 15 Oct 2024 15:08:40 +0100
Metin Kaya <metin.kaya@arm.com> wrote:

> Implement test cases to confirm existing dynamic event types (kprobe,
> kretprobe, uprobe, uretprobe and eprobe) are really preserved during
> "trace-cmd reset".
> 
> Verify synthetic events by inserting a hook to
> test_trace_sqlhist_hist().
> 
> While we are in the neighborhood, fix typo "ceated".
> 
> TODO: I'm unable to prevent uprobes/uretprobes from being destroyed
> during reset.

That's not a bug with this code. It's a bug with libtracefs. I'll fix it.

> 
> Link: https://lore.kernel.org/linux-trace-devel/20241014175905.03bec85a@gandalf.local.home
> 
> Signed-off-by: Metin Kaya <metin.kaya@arm.com>
> ---
>  utest/tracecmd-utest.c | 161 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 160 insertions(+), 1 deletion(-)
> 
> diff --git a/utest/tracecmd-utest.c b/utest/tracecmd-utest.c
> index 164f5da1..b2f6b65b 100644
> --- a/utest/tracecmd-utest.c
> +++ b/utest/tracecmd-utest.c
> @@ -352,6 +352,11 @@ static void test_trace_sqlhist_hist(void)
>  	sleep(1);
>  	ret = grep_match(SYNTH_EVENT ":", "show", NULL);
>  	CU_TEST(ret == 0);
> +	/* Ensure synthetic events remain untouched after "trace-cmd reset -k synth". */
> +	ret = run_trace("reset", "-k", "synth", NULL);
> +	CU_TEST(ret == 0);
> +	ret = grep_match(SYNTH_EVENT, "stat", NULL);
> +	CU_TEST(ret == 0);
>  
>  	tracefs_instance_reset(NULL);
>  }
> @@ -598,6 +603,159 @@ static void test_trace_library_read_back(void)
>  	tracecmd_close(handle);
>  }
>  
> +static void test_trace_reset_kprobe(void)
> +{
> +	int ret;
> +	FILE *fp;
> +
> +	/* Create a simple kprobe for do_sys_open */
> +	fp = fopen("/sys/kernel/tracing/kprobe_events", "w");
> +	CU_TEST(fp != NULL);
> +	fprintf(fp, "p do_sys_open");
> +	fclose(fp);

This is open coded of:

	ret = tracefs_instance_file_write(NULL, "kprobe_events", "p do_sys_open");
	CU_TEST(ret > 0);

And there's no guarantee that tracefs will be mounted at
/sys/kernel/tracing, so the above is incorrect anyway.

> +
> +	/* Ensure the kprobe is listed in "trace-cmd stat" output. */
> +	ret = grep_match("p:kprobes/p_do_sys_open_0 do_sys_open", "stat", NULL);
> +	CU_TEST(ret == 0);
> +
> +	/* Issue "trace-cmd reset", but keep kprobes. */
> +	ret = run_trace("reset", "-k", "kprobe", NULL);
> +	CU_TEST(ret == 0);
> +
> +	/* Verify the kprobe's existence after reset. */
> +	ret = grep_match("p:kprobes/p_do_sys_open_0 do_sys_open", "stat", NULL);
> +	CU_TEST(ret == 0);
> +}
> +
> +static void test_trace_reset_kretprobe(void)
> +{
> +	int ret;
> +	FILE *fp;
> +
> +	/* Create a simple kretprobe for do_sys_open */
> +	fp = fopen("/sys/kernel/tracing/kprobe_events", "w");
> +	CU_TEST(fp != NULL);
> +	fprintf(fp, "r do_sys_open");
> +	fclose(fp);

Use tracefs_instance_file_write() here too.

> +
> +	/* Ensure the kretprobe is listed in "trace-cmd stat" output. */
> +	ret = grep_match("r128:kprobes/r_do_sys_open_0 do_sys_open", "stat", NULL);

Note, this failed for me, because mine had "r16:kprobes..."

> +	CU_TEST(ret == 0);
> +
> +	/* Issue "trace-cmd reset", but keep kretprobes. */
> +	ret = run_trace("reset", "-k", "kretprobe", NULL);
> +	CU_TEST(ret == 0);
> +
> +	/* Verify the kretprobe's existence after reset. */
> +	ret = grep_match("r128:kprobes/r_do_sys_open_0 do_sys_open", "stat", NULL);
> +	CU_TEST(ret == 0);
> +}
> +
> +static void test_trace_reset_uprobe(void)
> +{
> +	int ret;
> +	FILE *fp;
> +
> +	/* Create a simple uprobe for do_sys_open */
> +	fp = fopen("/sys/kernel/tracing/uprobe_events", "w");
> +	CU_TEST(fp != NULL);
> +	fprintf(fp, "p /bin/bash:0x4245c0");
> +	fclose(fp);

Ditto.

> +
> +	/* Ensure the uprobe is listed in "trace-cmd stat" output. */
> +	ret = grep_match("p:uprobes/p_bash_0x4245c0 /bin/bash:0x00000000004245c0", "stat", NULL);
> +	CU_TEST(ret == 0);
> +
> +	/* Issue "trace-cmd reset", but keep uprobes. */
> +	ret = run_trace("reset", "-k", "uprobe", NULL);
> +	CU_TEST(ret == 0);
> +
> +	/* Verify the uprobe's existence after reset. */
> +	ret = grep_match("p:uprobes/p_bash_0x4245c0 /bin/bash:0x00000000004245c0", "stat", NULL);
> +	CU_TEST(ret == 0);
> +}
> +
> +static void test_trace_reset_uretprobe(void)
> +{
> +	int ret;
> +	FILE *fp;
> +
> +	/* Create a simple uretprobe for do_sys_open */
> +	fp = fopen("/sys/kernel/tracing/uprobe_events", "w");
> +	CU_TEST(fp != NULL);
> +	fprintf(fp, "r /bin/bash:0x4245c0");
> +	fclose(fp);

Ditto.

> +
> +	/* Ensure the uretprobe is listed in "trace-cmd stat" output. */
> +	ret = grep_match("r:uprobes/p_bash_0x4245c0 /bin/bash:0x00000000004245c0", "stat", NULL);
> +	CU_TEST(ret == 0);
> +
> +	/* Issue "trace-cmd reset", but keep uretprobes. */
> +	ret = run_trace("reset", "-k", "uretprobe", NULL);
> +	CU_TEST(ret == 0);
> +
> +	/* Verify the uretprobe's existence after reset. */
> +	ret = grep_match("r:uprobes/p_bash_0x4245c0 /bin/bash:0x00000000004245c0", "stat", NULL);
> +	CU_TEST(ret == 0);
> +}
> +
> +static void test_trace_reset_eprobe(void)
> +{
> +	int ret;
> +	bool matched = false;
> +	size_t l = 0;
> +	ssize_t n;
> +	char *buf = NULL;
> +	struct tracefs_dynevent *deprobe;
> +	FILE *fp;
> +
> +	deprobe = tracefs_eprobe_alloc(NULL, "sopen_in", "syscalls", "sys_enter_openat", NULL);
> +	CU_TEST(deprobe != NULL);
> +
> +	ret = tracefs_dynevent_create(deprobe);
> +	CU_TEST(ret == 0);
> +
> +	/* Issue "trace-cmd reset", but keep eprobes. */
> +	ret = run_trace("reset", "-k", "eprobe", NULL);
> +	CU_TEST(ret == 0);
> +
> +	/* Verify the eprobe's existence after reset. */
> +	fp = fopen("/sys/kernel/tracing/dynamic_events", "r");
> +	CU_TEST(fp != NULL);

	int fd;

	fd = tracefs_instance_file_open(NULL, "dynamic_events", O_RDONLY);
	fp = fdopen(fd, "r");

> +
> +	while ((n = getline(&buf, &l, fp)) != -1) {
> +		if (!strcmp(buf, "e:eprobes/sopen_in syscalls.sys_enter_openat\n")) {
> +			matched = true;
> +			break;
> +		}
> +	}
> +	free(buf);

-- Steve

> +
> +	fclose(fp);
> +
> +	CU_TEST(matched == true);
> +
> +	ret = tracefs_dynevent_destroy(deprobe, false);
> +	CU_TEST(ret == 0);
> +
> +	tracefs_dynevent_free(deprobe);
> +}
> +
> +static void test_trace_reset(void)
> +{
> +	int ret;
> +
> +	test_trace_reset_kprobe();
> +	test_trace_reset_kretprobe();
> +	test_trace_reset_uprobe();
> +	test_trace_reset_uretprobe();
> +	test_trace_reset_eprobe();
> +
> +	/* Destroy all dynamic events. */
> +	ret = run_trace("reset", NULL);
> +	CU_TEST(ret == 0);
> +}
> +
>  static int test_suite_destroy(void)
>  {
>  	unlink(TRACECMD_FILE);
> @@ -639,7 +797,7 @@ void test_tracecmd_lib(void)
>  
>  	suite = CU_add_suite(TRACECMD_SUITE, test_suite_init, test_suite_destroy);
>  	if (suite == NULL) {
> -		fprintf(stderr, "Suite \"%s\" cannot be ceated\n", TRACECMD_SUITE);
> +		fprintf(stderr, "Suite \"%s\" cannot be created\n", TRACECMD_SUITE);
>  		return;
>  	}
>  	CU_add_test(suite, "Simple record and report",
> @@ -656,4 +814,5 @@ void test_tracecmd_lib(void)
>  		    test_trace_library_read_back);
>  	CU_add_test(suite, "Test max length",
>  		    test_trace_record_max);
> +	CU_add_test(suite, "Simple reset", test_trace_reset);
>  }
Steven Rostedt Oct. 15, 2024, 5:38 p.m. UTC | #2
On Tue, 15 Oct 2024 12:38:31 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

> > +
> > +	/* Ensure the kretprobe is listed in "trace-cmd stat" output. */
> > +	ret = grep_match("r128:kprobes/r_do_sys_open_0 do_sys_open", "stat", NULL);  
> 
> Note, this failed for me, because mine had "r16:kprobes..."

BTW, this works though:

	ret = grep_match("r[0-9]*:kprobes/r_do_sys_open_0 do_sys_open", "stat", NULL);  

-- Steve
diff mbox series

Patch

diff --git a/utest/tracecmd-utest.c b/utest/tracecmd-utest.c
index 164f5da1..b2f6b65b 100644
--- a/utest/tracecmd-utest.c
+++ b/utest/tracecmd-utest.c
@@ -352,6 +352,11 @@  static void test_trace_sqlhist_hist(void)
 	sleep(1);
 	ret = grep_match(SYNTH_EVENT ":", "show", NULL);
 	CU_TEST(ret == 0);
+	/* Ensure synthetic events remain untouched after "trace-cmd reset -k synth". */
+	ret = run_trace("reset", "-k", "synth", NULL);
+	CU_TEST(ret == 0);
+	ret = grep_match(SYNTH_EVENT, "stat", NULL);
+	CU_TEST(ret == 0);
 
 	tracefs_instance_reset(NULL);
 }
@@ -598,6 +603,159 @@  static void test_trace_library_read_back(void)
 	tracecmd_close(handle);
 }
 
+static void test_trace_reset_kprobe(void)
+{
+	int ret;
+	FILE *fp;
+
+	/* Create a simple kprobe for do_sys_open */
+	fp = fopen("/sys/kernel/tracing/kprobe_events", "w");
+	CU_TEST(fp != NULL);
+	fprintf(fp, "p do_sys_open");
+	fclose(fp);
+
+	/* Ensure the kprobe is listed in "trace-cmd stat" output. */
+	ret = grep_match("p:kprobes/p_do_sys_open_0 do_sys_open", "stat", NULL);
+	CU_TEST(ret == 0);
+
+	/* Issue "trace-cmd reset", but keep kprobes. */
+	ret = run_trace("reset", "-k", "kprobe", NULL);
+	CU_TEST(ret == 0);
+
+	/* Verify the kprobe's existence after reset. */
+	ret = grep_match("p:kprobes/p_do_sys_open_0 do_sys_open", "stat", NULL);
+	CU_TEST(ret == 0);
+}
+
+static void test_trace_reset_kretprobe(void)
+{
+	int ret;
+	FILE *fp;
+
+	/* Create a simple kretprobe for do_sys_open */
+	fp = fopen("/sys/kernel/tracing/kprobe_events", "w");
+	CU_TEST(fp != NULL);
+	fprintf(fp, "r do_sys_open");
+	fclose(fp);
+
+	/* Ensure the kretprobe is listed in "trace-cmd stat" output. */
+	ret = grep_match("r128:kprobes/r_do_sys_open_0 do_sys_open", "stat", NULL);
+	CU_TEST(ret == 0);
+
+	/* Issue "trace-cmd reset", but keep kretprobes. */
+	ret = run_trace("reset", "-k", "kretprobe", NULL);
+	CU_TEST(ret == 0);
+
+	/* Verify the kretprobe's existence after reset. */
+	ret = grep_match("r128:kprobes/r_do_sys_open_0 do_sys_open", "stat", NULL);
+	CU_TEST(ret == 0);
+}
+
+static void test_trace_reset_uprobe(void)
+{
+	int ret;
+	FILE *fp;
+
+	/* Create a simple uprobe for do_sys_open */
+	fp = fopen("/sys/kernel/tracing/uprobe_events", "w");
+	CU_TEST(fp != NULL);
+	fprintf(fp, "p /bin/bash:0x4245c0");
+	fclose(fp);
+
+	/* Ensure the uprobe is listed in "trace-cmd stat" output. */
+	ret = grep_match("p:uprobes/p_bash_0x4245c0 /bin/bash:0x00000000004245c0", "stat", NULL);
+	CU_TEST(ret == 0);
+
+	/* Issue "trace-cmd reset", but keep uprobes. */
+	ret = run_trace("reset", "-k", "uprobe", NULL);
+	CU_TEST(ret == 0);
+
+	/* Verify the uprobe's existence after reset. */
+	ret = grep_match("p:uprobes/p_bash_0x4245c0 /bin/bash:0x00000000004245c0", "stat", NULL);
+	CU_TEST(ret == 0);
+}
+
+static void test_trace_reset_uretprobe(void)
+{
+	int ret;
+	FILE *fp;
+
+	/* Create a simple uretprobe for do_sys_open */
+	fp = fopen("/sys/kernel/tracing/uprobe_events", "w");
+	CU_TEST(fp != NULL);
+	fprintf(fp, "r /bin/bash:0x4245c0");
+	fclose(fp);
+
+	/* Ensure the uretprobe is listed in "trace-cmd stat" output. */
+	ret = grep_match("r:uprobes/p_bash_0x4245c0 /bin/bash:0x00000000004245c0", "stat", NULL);
+	CU_TEST(ret == 0);
+
+	/* Issue "trace-cmd reset", but keep uretprobes. */
+	ret = run_trace("reset", "-k", "uretprobe", NULL);
+	CU_TEST(ret == 0);
+
+	/* Verify the uretprobe's existence after reset. */
+	ret = grep_match("r:uprobes/p_bash_0x4245c0 /bin/bash:0x00000000004245c0", "stat", NULL);
+	CU_TEST(ret == 0);
+}
+
+static void test_trace_reset_eprobe(void)
+{
+	int ret;
+	bool matched = false;
+	size_t l = 0;
+	ssize_t n;
+	char *buf = NULL;
+	struct tracefs_dynevent *deprobe;
+	FILE *fp;
+
+	deprobe = tracefs_eprobe_alloc(NULL, "sopen_in", "syscalls", "sys_enter_openat", NULL);
+	CU_TEST(deprobe != NULL);
+
+	ret = tracefs_dynevent_create(deprobe);
+	CU_TEST(ret == 0);
+
+	/* Issue "trace-cmd reset", but keep eprobes. */
+	ret = run_trace("reset", "-k", "eprobe", NULL);
+	CU_TEST(ret == 0);
+
+	/* Verify the eprobe's existence after reset. */
+	fp = fopen("/sys/kernel/tracing/dynamic_events", "r");
+	CU_TEST(fp != NULL);
+
+	while ((n = getline(&buf, &l, fp)) != -1) {
+		if (!strcmp(buf, "e:eprobes/sopen_in syscalls.sys_enter_openat\n")) {
+			matched = true;
+			break;
+		}
+	}
+	free(buf);
+
+	fclose(fp);
+
+	CU_TEST(matched == true);
+
+	ret = tracefs_dynevent_destroy(deprobe, false);
+	CU_TEST(ret == 0);
+
+	tracefs_dynevent_free(deprobe);
+}
+
+static void test_trace_reset(void)
+{
+	int ret;
+
+	test_trace_reset_kprobe();
+	test_trace_reset_kretprobe();
+	test_trace_reset_uprobe();
+	test_trace_reset_uretprobe();
+	test_trace_reset_eprobe();
+
+	/* Destroy all dynamic events. */
+	ret = run_trace("reset", NULL);
+	CU_TEST(ret == 0);
+}
+
 static int test_suite_destroy(void)
 {
 	unlink(TRACECMD_FILE);
@@ -639,7 +797,7 @@  void test_tracecmd_lib(void)
 
 	suite = CU_add_suite(TRACECMD_SUITE, test_suite_init, test_suite_destroy);
 	if (suite == NULL) {
-		fprintf(stderr, "Suite \"%s\" cannot be ceated\n", TRACECMD_SUITE);
+		fprintf(stderr, "Suite \"%s\" cannot be created\n", TRACECMD_SUITE);
 		return;
 	}
 	CU_add_test(suite, "Simple record and report",
@@ -656,4 +814,5 @@  void test_tracecmd_lib(void)
 		    test_trace_library_read_back);
 	CU_add_test(suite, "Test max length",
 		    test_trace_record_max);
+	CU_add_test(suite, "Simple reset", test_trace_reset);
 }