Re: [PATCH] trace-cmd utest: Add test cases for trace-cmd reset

Steven Rostedt <[email protected]>
Newsgroups org.kernel.vger.linux-trace-devel
Message-ID <[email protected]>
On Tue, 15 Oct 2024 15:08:40 +0100
Metin Kaya <[email protected]> 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/[email protected]
> 
> Signed-off-by: Metin Kaya <[email protected]>
> ---
>  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);
>  }
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.