From: "Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com>
To: rostedt@goodmis.org
Cc: linux-trace-devel@vger.kernel.org
Subject: [PATCH 08/12] libtracefs: Extend kprobes unit test
Date: Thu, 28 Oct 2021 15:09:03 +0300 [thread overview]
Message-ID: <20211028120907.101847-9-tz.stoyanov@gmail.com> (raw)
In-Reply-To: <20211028120907.101847-1-tz.stoyanov@gmail.com>
As there are a lot of changes in the libtracefs kprobes APIs, the unit
test of that functionality should be updated. A new test section is
added, for testing the all kprobes APIs.
Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
utest/tracefs-utest.c | 414 +++++++++++++++++++++++++-----------------
1 file changed, 244 insertions(+), 170 deletions(-)
diff --git a/utest/tracefs-utest.c b/utest/tracefs-utest.c
index 7c1a84e..0a17b82 100644
--- a/utest/tracefs-utest.c
+++ b/utest/tracefs-utest.c
@@ -28,22 +28,6 @@
#define TRACE_ON "tracing_on"
#define TRACE_CLOCK "trace_clock"
-#define KPROBE_EVENTS "kprobe_events"
-
-#define KPROBE_1_NAME "mkdir"
-#define KPROBE_1_GROUP "kprobes"
-#define KPROBE_1_ADDR "do_mkdirat"
-#define KPROBE_1_FMT "path=+u0($arg2):ustring"
-
-#define KPROBE_2_NAME "open"
-#define KPROBE_2_GROUP "myprobe"
-#define KPROBE_2_ADDR "do_sys_openat2"
-#define KPROBE_2_FMT "file=+u0($arg2):ustring flags=+0($arg3):x64"
-
-#define KRETPROBE_NAME "retopen"
-#define KRETPROBE_ADDR "do_sys_openat2"
-#define KRETPROBE_FMT "ret=$retval"
-
#define SQL_1_EVENT "wakeup_1"
#define SQL_1_SQL "select sched_switch.next_pid as woke_pid, sched_waking.common_pid as waking_pid from sched_waking join sched_switch on sched_switch.next_pid = sched_waking.pid"
@@ -457,28 +441,264 @@ static void test_instance_file_read(struct tracefs_instance *inst, const char *f
free(file);
}
+#define KPROBE_DEFAULT_GROUP "kprobes"
+struct kprobe_test {
+ enum tracefs_kprobe_type type;
+ char *prefix;
+ char *system;
+ char *event;
+ char *address;
+ char *format;
+};
+
+static bool check_kprobes(struct kprobe_test *kprobes, int count,
+ struct tracefs_dynevent **devents, bool in_system)
+{
+
+ enum tracefs_kprobe_type ktype;
+ char *ename;
+ char *kaddress;
+ char *kevent;
+ char *ksystem;
+ char *kformat;
+ char *kprefix;
+ int found = 0;
+ int ret;
+ int i, j;
+
+ for (i = 0; devents[i]; i++) {
+ ktype = tracefs_kprobe_info(devents[i], &ksystem,
+ &kevent, &kprefix, &kaddress, &kformat);
+ for (j = 0; j < count; j++) {
+ if (ktype != kprobes[j].type)
+ continue;
+ if (kprobes[j].event)
+ ename = kprobes[j].event;
+ else
+ ename = kprobes[j].address;
+ if (strcmp(ename, kevent))
+ continue;
+ if (kprobes[j].system) {
+ CU_TEST(strcmp(kprobes[j].system, ksystem) == 0);
+ } else {
+ CU_TEST(strcmp(KPROBE_DEFAULT_GROUP, ksystem) == 0);
+ }
+ CU_TEST(strcmp(kprobes[j].address, kaddress) == 0);
+ CU_TEST(strcmp(kprobes[j].format, kformat) == 0);
+ if (kprobes[j].prefix)
+ CU_TEST(strcmp(kprobes[j].prefix, kprefix) == 0);
+ ret = tracefs_event_enable(test_instance, ksystem, kevent);
+ if (in_system) {
+ CU_TEST(ret == 0);
+ } else {
+ CU_TEST(ret != 0);
+ }
+ ret = tracefs_event_disable(test_instance, ksystem, kevent);
+ if (in_system) {
+ CU_TEST(ret == 0);
+ } else {
+ CU_TEST(ret != 0);
+ }
+
+ found++;
+ break;
+ }
+ free(ksystem);
+ free(kevent);
+ free(kprefix);
+ free(kaddress);
+ free(kformat);
+ }
+
+ CU_TEST(found == count);
+ if (found != count)
+ return false;
+
+ return true;
+}
+
+#define KPROBE_COUNT 2
+#define KRETPROBE_COUNT 2
+static void test_kprobes(void)
+{
+ char *tmp;
+
+ struct kprobe_test ktests[KPROBE_COUNT] = {
+ { TRACEFS_KPROBE, "p:", NULL, "mkdir", "do_mkdirat", "path=+u0($arg2):ustring" },
+ { TRACEFS_KPROBE, "p:", "ptest", "open", "do_sys_openat2",
+ "file=+u0($arg2):ustring flags=+0($arg3):x64" },
+ };
+ struct kprobe_test kretests[KRETPROBE_COUNT] = {
+ { TRACEFS_KRETPROBE, NULL, NULL, "retopen", "do_sys_openat2", "ret=$retval" },
+ { TRACEFS_KRETPROBE, NULL, NULL, NULL, "do_sys_open", "ret=$retval" },
+ };
+ struct tracefs_dynevent *dkretprobe[KRETPROBE_COUNT + 1];
+ struct tracefs_dynevent *dkprobe[KPROBE_COUNT + 1];
+ struct tracefs_dynevent **devents;
+ int ret;
+ int i;
+
+ /* Invalid parameters */
+ CU_TEST(tracefs_kprobe_alloc("test", NULL, NULL, "test") == NULL);
+ CU_TEST(tracefs_kretprobe_alloc("test", NULL, NULL, "test", 0) == NULL);
+ CU_TEST(tracefs_kprobe_alloc("test", NULL, "test", NULL) == NULL);
+ CU_TEST(tracefs_kretprobe_alloc("test", NULL, "test", NULL, 0) == NULL);
+ CU_TEST(tracefs_kprobe_create(NULL) != 0);
+ CU_TEST(tracefs_kprobe_info(NULL, &tmp, &tmp, &tmp, &tmp, &tmp) == TRACEFS_ALL_KPROBES);
+ CU_TEST(tracefs_kprobe_raw("test", "test", NULL, "test") != 0);
+ CU_TEST(tracefs_kretprobe_raw("test", "test", NULL, "test") != 0);
+ CU_TEST(tracefs_kprobe_raw("test", "test", "test", NULL) != 0);
+ CU_TEST(tracefs_kretprobe_raw("test", "test", "test", NULL) != 0);
+
+ /* kprobes APIs */
+ ret = tracefs_kprobe_destroy(NULL, true);
+ CU_TEST(ret == 0);
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == 0);
+ CU_TEST(devents == NULL);
+
+ for (i = 0; i < KPROBE_COUNT; i++) {
+ dkprobe[i] = tracefs_kprobe_alloc(ktests[i].system, ktests[i].event,
+ ktests[i].address, ktests[i].format);
+ CU_TEST(dkprobe[i] != NULL);
+ }
+ dkprobe[i] = NULL;
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == 0);
+ CU_TEST(devents == NULL);
+ CU_TEST(check_kprobes(ktests, KPROBE_COUNT, dkprobe, false));
+
+ for (i = 0; i < KRETPROBE_COUNT; i++) {
+ dkretprobe[i] = tracefs_kretprobe_alloc(kretests[i].system, kretests[i].event,
+ kretests[i].address, kretests[i].format, 0);
+ CU_TEST(dkretprobe[i] != NULL);
+ }
+ dkretprobe[i] = NULL;
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == 0);
+ CU_TEST(devents == NULL);
+ CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, dkretprobe, false));
+
+ for (i = 0; i < KPROBE_COUNT; i++) {
+ CU_TEST(tracefs_kprobe_create(dkprobe[i]) == 0);
+ }
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == KPROBE_COUNT);
+ CU_TEST(devents != NULL);
+ CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true));
+ CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, dkretprobe, false));
+ tracefs_dynevent_list_free(&devents);
+ devents = NULL;
+
+ for (i = 0; i < KRETPROBE_COUNT; i++) {
+ CU_TEST(tracefs_kprobe_create(dkretprobe[i]) == 0);
+ }
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == (KPROBE_COUNT + KRETPROBE_COUNT));
+ CU_TEST(devents != NULL);
+ CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true));
+ CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, devents, true));
+ tracefs_dynevent_list_free(&devents);
+ devents = NULL;
+
+ for (i = 0; i < KRETPROBE_COUNT; i++) {
+ CU_TEST(tracefs_kprobe_destroy(dkretprobe[i], false) == 0);
+ }
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == KPROBE_COUNT);
+ CU_TEST(devents != NULL);
+ CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true));
+ CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, dkretprobe, false));
+ tracefs_dynevent_list_free(&devents);
+ devents = NULL;
+
+ for (i = 0; i < KPROBE_COUNT; i++) {
+ CU_TEST(tracefs_kprobe_destroy(dkprobe[i], false) == 0);
+ }
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == 0);
+ CU_TEST(devents == NULL);
+ CU_TEST(check_kprobes(ktests, KPROBE_COUNT, dkprobe, false));
+ CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, dkretprobe, false));
+ tracefs_dynevent_list_free(&devents);
+ devents = NULL;
+
+ for (i = 0; i < KPROBE_COUNT; i++)
+ tracefs_kprobe_free(dkprobe[i]);
+ for (i = 0; i < KRETPROBE_COUNT; i++)
+ tracefs_kprobe_free(dkretprobe[i]);
+
+ /* kprobes raw APIs */
+ ret = tracefs_kprobe_destroy(NULL, true);
+ CU_TEST(ret == 0);
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == 0);
+ CU_TEST(devents == NULL);
+
+ for (i = 0; i < KPROBE_COUNT; i++) {
+ ret = tracefs_kprobe_raw(ktests[i].system, ktests[i].event,
+ ktests[i].address, ktests[i].format);
+ CU_TEST(ret == 0);
+ }
+
+ ret = tracefs_kprobes_get(TRACEFS_KPROBE, &devents);
+ CU_TEST(ret == KPROBE_COUNT);
+ CU_TEST(devents != NULL);
+ CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true));
+ tracefs_dynevent_list_free(&devents);
+ devents = NULL;
+
+ for (i = 0; i < KRETPROBE_COUNT; i++) {
+ ret = tracefs_kretprobe_raw(kretests[i].system, kretests[i].event,
+ kretests[i].address, kretests[i].format);
+ CU_TEST(ret == 0);
+ }
+
+ ret = tracefs_kprobes_get(TRACEFS_KPROBE, &devents);
+ CU_TEST(ret == KPROBE_COUNT);
+ CU_TEST(devents != NULL);
+ CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true));
+ tracefs_dynevent_list_free(&devents);
+ devents = NULL;
+
+ ret = tracefs_kprobes_get(TRACEFS_KRETPROBE, &devents);
+ CU_TEST(ret == KRETPROBE_COUNT);
+ CU_TEST(devents != NULL);
+ CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, devents, true));
+ tracefs_dynevent_list_free(&devents);
+ devents = NULL;
+
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == (KPROBE_COUNT + KRETPROBE_COUNT));
+ CU_TEST(devents != NULL);
+ CU_TEST(check_kprobes(ktests, KPROBE_COUNT, devents, true));
+ CU_TEST(check_kprobes(kretests, KRETPROBE_COUNT, devents, true));
+ tracefs_dynevent_list_free(&devents);
+ devents = NULL;
+
+ ret = tracefs_kprobe_destroy(NULL, true);
+ CU_TEST(ret == 0);
+ ret = tracefs_kprobes_get(TRACEFS_ALL_KPROBES, &devents);
+ CU_TEST(ret == 0);
+ CU_TEST(devents == NULL);
+}
+
static void test_instance_file(void)
{
struct tracefs_instance *instance = NULL;
struct tracefs_instance *second = NULL;
- enum tracefs_kprobe_type type;
const char *name = get_rand_str();
const char *inst_name = NULL;
const char *tdir;
char *inst_file;
char *inst_dir;
struct stat st;
- char **kprobes;
- char *kformat;
- char *ktype;
- char *kaddr;
- char *fname;
char *file1;
char *file2;
char *tracer;
+ char *fname;
int size;
int ret;
- int i;
tdir = tracefs_tracing_dir();
CU_TEST(tdir != NULL);
@@ -541,153 +761,6 @@ static void test_instance_file(void)
free(file1);
free(file2);
- ret = tracefs_kprobe_clear_all(true);
- CU_TEST(ret == 0);
- ret = tracefs_kprobe_raw(NULL, KPROBE_1_NAME, KPROBE_1_ADDR, KPROBE_1_FMT);
- CU_TEST(ret == 0);
- ret = tracefs_kprobe_raw(KPROBE_2_GROUP, KPROBE_2_NAME, KPROBE_2_ADDR,
- KPROBE_2_FMT);
- CU_TEST(ret == 0);
-
- ret = tracefs_kretprobe_raw(KPROBE_2_GROUP, KRETPROBE_NAME, KRETPROBE_ADDR,
- KRETPROBE_FMT);
- CU_TEST(ret == 0);
-
- type = tracefs_kprobe_info(KPROBE_1_GROUP, KPROBE_1_NAME, &ktype,
- &kaddr, &kformat);
- CU_TEST(type == TRACEFS_KPROBE);
- CU_TEST(ktype && *ktype == 'p');
- CU_TEST(kaddr && !strcmp(kaddr, KPROBE_1_ADDR));
- CU_TEST(kformat && !strcmp(kformat, KPROBE_1_FMT));
- free(ktype);
- free(kaddr);
- free(kformat);
-
- type = tracefs_kprobe_info(KPROBE_2_GROUP, KPROBE_2_NAME, &ktype,
- &kaddr, &kformat);
- CU_TEST(type == TRACEFS_KPROBE);
- CU_TEST(ktype && *ktype == 'p');
- CU_TEST(kaddr && !strcmp(kaddr, KPROBE_2_ADDR));
- CU_TEST(kformat && !strcmp(kformat, KPROBE_2_FMT));
- free(ktype);
- free(kaddr);
- free(kformat);
-
- type = tracefs_kprobe_info(KPROBE_2_GROUP, KRETPROBE_NAME, &ktype,
- &kaddr, &kformat);
- CU_TEST(type == TRACEFS_KRETPROBE);
- CU_TEST(ktype && *ktype == 'r');
- CU_TEST(kaddr && !strcmp(kaddr, KRETPROBE_ADDR));
- CU_TEST(kformat && !strcmp(kformat, KRETPROBE_FMT));
- free(ktype);
- free(kaddr);
- free(kformat);
-
- kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES);
- CU_TEST(kprobes != NULL);
-
- for (i = 0; kprobes[i]; i++) {
- char *system = strtok(kprobes[i], "/");
- char *event = strtok(NULL, "");
- bool found = false;
- if (!strcmp(system, KPROBE_1_GROUP)) {
- CU_TEST(!strcmp(event, KPROBE_1_NAME));
- found = true;
- } else if (!strcmp(system, KPROBE_2_GROUP)) {
- switch (tracefs_kprobe_info(system, event, NULL, NULL, NULL)) {
- case TRACEFS_KPROBE:
- CU_TEST(!strcmp(event, KPROBE_2_NAME));
- found = true;
- break;
- case TRACEFS_KRETPROBE:
- CU_TEST(!strcmp(event, KRETPROBE_NAME));
- found = true;
- break;
- default:
- break;
- }
- }
- CU_TEST(found);
- }
- tracefs_list_free(kprobes);
- CU_TEST(i == 3);
-
- kprobes = tracefs_kprobes_get(TRACEFS_KPROBE);
- CU_TEST(kprobes != NULL);
-
- for (i = 0; kprobes[i]; i++) {
- char *system = strtok(kprobes[i], "/");
- char *event = strtok(NULL, "");
- bool found = false;
- if (!strcmp(system, KPROBE_1_GROUP)) {
- CU_TEST(!strcmp(event, KPROBE_1_NAME));
- found = true;
- } else if (!strcmp(system, KPROBE_2_GROUP)) {
- CU_TEST(!strcmp(event, KPROBE_2_NAME));
- found = true;
- }
- CU_TEST(found);
- }
- tracefs_list_free(kprobes);
- CU_TEST(i == 2);
-
- kprobes = tracefs_kprobes_get(TRACEFS_KRETPROBE);
- CU_TEST(kprobes != NULL);
-
- for (i = 0; kprobes[i]; i++) {
- char *system = strtok(kprobes[i], "/");
- char *event = strtok(NULL, "");
- bool found = false;
- if (!strcmp(system, KPROBE_2_GROUP)) {
- CU_TEST(!strcmp(event, KRETPROBE_NAME));
- found = true;
- }
- CU_TEST(found);
- }
- tracefs_list_free(kprobes);
- CU_TEST(i == 1);
-
- ret = tracefs_event_enable(instance, KPROBE_1_GROUP, KPROBE_1_NAME);
- CU_TEST(ret == 0);
- ret = tracefs_event_enable(instance, KPROBE_2_GROUP, KPROBE_2_NAME);
- CU_TEST(ret == 0);
- ret = tracefs_event_enable(instance, KPROBE_2_GROUP, KRETPROBE_NAME);
- CU_TEST(ret == 0);
-
- ret = tracefs_kprobe_clear_all(false);
- CU_TEST(ret < 0);
-
- ret = tracefs_kprobe_clear_probe(KPROBE_2_GROUP, NULL, false);
- CU_TEST(ret < 0);
-
- ret = tracefs_kprobe_clear_probe(KPROBE_2_GROUP, NULL, true);
- CU_TEST(ret == 0);
-
- kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES);
- CU_TEST(kprobes != NULL);
-
- for (i = 0; kprobes[i]; i++) {
- char *system = strtok(kprobes[i], "/");
- char *event = strtok(NULL, "");
- bool found = false;
- if (!strcmp(system, KPROBE_1_GROUP)) {
- CU_TEST(!strcmp(event, KPROBE_1_NAME));
- found = true;
- }
- CU_TEST(found);
- }
- tracefs_list_free(kprobes);
- CU_TEST(i == 1);
-
- ret = tracefs_kprobe_clear_all(true);
- CU_TEST(ret == 0);
-
- kprobes = tracefs_kprobes_get(TRACEFS_ALL_KPROBES);
- CU_TEST(kprobes != NULL);
-
- CU_TEST(kprobes[0] == NULL);
- tracefs_list_free(kprobes);
-
tracefs_put_tracing_file(inst_file);
free(fname);
@@ -1442,4 +1515,5 @@ void test_tracefs_lib(void)
test_custom_trace_dir);
CU_add_test(suite, "ftrace marker",
test_ftrace_marker);
+ CU_add_test(suite, "kprobes", test_kprobes);
}
--
2.31.1
next prev parent reply other threads:[~2021-10-28 12:09 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-28 12:08 [PATCH 00/12] libtracefs dynamic events support Tzvetomir Stoyanov (VMware)
2021-10-28 12:08 ` [PATCH 01/12] libtracefs: Add new internal APIs for dynamic events Tzvetomir Stoyanov (VMware)
2021-10-28 21:41 ` Steven Rostedt
2021-10-29 2:46 ` Tzvetomir Stoyanov
2021-10-29 3:09 ` Steven Rostedt
2021-10-28 12:08 ` [PATCH 02/12] libtracefs: Rename tracefs_get_kprobes API Tzvetomir Stoyanov (VMware)
2021-10-28 12:08 ` [PATCH 03/12] libtracefs: New kprobes APIs Tzvetomir Stoyanov (VMware)
2021-10-29 2:55 ` Steven Rostedt
2021-10-28 12:08 ` [PATCH 04/12] libtracefs: Remove redundant " Tzvetomir Stoyanov (VMware)
2021-10-28 12:09 ` [PATCH 05/12] libtracefs: Reimplement tracefs_kprobes_get API Tzvetomir Stoyanov (VMware)
2021-10-29 3:01 ` Steven Rostedt
2021-10-28 12:09 ` [PATCH 06/12] libtracefs: Change tracefs_kprobe_info API Tzvetomir Stoyanov (VMware)
2021-10-28 12:09 ` [PATCH 07/12] libtracefs: Reimplement kprobe raw APIs Tzvetomir Stoyanov (VMware)
2021-10-28 12:09 ` Tzvetomir Stoyanov (VMware) [this message]
2021-10-28 12:09 ` [PATCH 09/12] libtracefs: Update kprobes man pages Tzvetomir Stoyanov (VMware)
2021-10-28 12:09 ` [PATCH 10/12] libtracefs: Rename tracefs_synth_init API Tzvetomir Stoyanov (VMware)
2021-10-28 12:09 ` [PATCH 11/12] libtracefs: Use the internal dynamic events API when creating synthetic events Tzvetomir Stoyanov (VMware)
2021-10-28 12:09 ` [PATCH 12/12] libtracefs: Document tracefs_dynevent_list_free() API Tzvetomir Stoyanov (VMware)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211028120907.101847-9-tz.stoyanov@gmail.com \
--to=tz.stoyanov@gmail.com \
--cc=linux-trace-devel@vger.kernel.org \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).