[PATCH v5 3/4] Add test for --decode-fds=eventfd

Sahil Siddiq icegambit91 at gmail.com
Thu May 23 14:43:33 UTC 2024


Add test for --decode-fds=eventfd.

* tests/.gitignore: Add eventfd-yy.
* tests/Makefile.am: Add eventfd-yy.
* tests/eventfd-yy.c: New file.
* tests/gen_tests.in: Add rule to generate test.

Signed-off-by: Sahil Siddiq <icegambit91 at gmail.com>
---
Changes v3 -> v5:
- tests/eventfd-yy.c:
  (procfs_check_avail_efd_data):
  - (matches): Use ++ instead of +=1.
  - Modify second "if" condition.

Changes v4 -> v5: None

 tests/.gitignore   |   1 +
 tests/Makefile.am  |   1 +
 tests/eventfd-yy.c | 196 +++++++++++++++++++++++++++++++++++++++++++++
 tests/gen_tests.in |   1 +
 4 files changed, 199 insertions(+)
 create mode 100644 tests/eventfd-yy.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 79d2f6148..2483f52a9 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -129,6 +129,7 @@ epoll_pwait2-y
 epoll_wait
 erestartsys
 eventfd
+eventfd-yy
 execve
 execve-v
 execveat
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ef6889862..64f32edd7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -142,6 +142,7 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	count-f \
 	delay \
 	detach-vfork \
+	eventfd-yy \
 	execve-v \
 	execveat-v \
 	fcntl--pidns-translation \
diff --git a/tests/eventfd-yy.c b/tests/eventfd-yy.c
new file mode 100644
index 000000000..14a15b7eb
--- /dev/null
+++ b/tests/eventfd-yy.c
@@ -0,0 +1,196 @@
+/*
+ * Test --decode-fds=eventfd option.
+ *
+ * Copyright (c) 2024 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "tests.h"
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/eventfd.h>
+
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+struct fdinfo {
+	const char *search_pfx;
+	size_t search_pfx_len;
+	bool avail;
+	void *data;
+};
+
+static void
+parse_fdinfo_efd_id(const char *value, void *data)
+{
+	int *efd_id = data;
+	*efd_id = (int)strtol(value, NULL, 10);
+
+	if (*efd_id < 0)
+		*efd_id = -1;
+}
+
+static size_t
+procfs_check_avail_efd_data(pid_t pid, int fd, struct fdinfo *fdinfo_lines,
+                            size_t fdinfo_array_size)
+{
+	char fdinfo_path[sizeof("/proc/%u/fdinfo/%u") + 2 * sizeof(int) * 3];
+	sprintf(fdinfo_path, "/proc/%u/fdinfo/%u", pid, fd);
+
+	FILE *f = fopen(fdinfo_path, "r");
+	if (!f)
+		perror_msg_and_fail("fopen");
+
+	char *line = NULL;
+	size_t sz = 0;
+	size_t matches = 0;
+
+	while (getline(&line, &sz, f) > 0) {
+		for (size_t i = 0; i < fdinfo_array_size; i++) {
+			const char *search_pfx = fdinfo_lines[i].search_pfx;
+			size_t search_pfx_len = fdinfo_lines[i].search_pfx_len;
+			if (!strncmp(line, search_pfx, search_pfx_len)) {
+				fdinfo_lines[i].avail = true;
+				matches++;
+				if (fdinfo_lines[i].data) {
+					const char *value = line + search_pfx_len;
+					parse_fdinfo_efd_id(value, fdinfo_lines[i].data);
+				}
+				break;
+			}
+		}
+	}
+
+	free(line);
+	fclose(f);
+
+	return matches;
+}
+
+static void
+print_eventfd_details(struct fdinfo *fdinfo_lines, size_t fdinfo_array_size,
+                      uint64_t efd_counter, int efd_semaphore)
+{
+	if (fdinfo_lines[0].avail) {
+		char efd_counter_str[sizeof("0xffffffffffffffff")];
+		memset(efd_counter_str, 0, sizeof("0xffffffffffffffff"));
+		sprintf(efd_counter_str, "0x%"PRIx64, efd_counter);
+		printf("<{eventfd-count=%s", efd_counter_str);
+
+		int efd_id = *(int *)fdinfo_lines[1].data;
+		if (efd_id != -1) {
+			printf(", eventfd-id=%d", efd_id);
+
+			if (fdinfo_lines[2].avail)
+				printf(", eventfd-semaphore=%d", efd_semaphore);
+		}
+
+		printf("}>");
+	}
+}
+
+int
+main(void)
+{
+	SKIP_IF_PROC_IS_UNAVAILABLE;
+
+	static const char efd_counter_pfx[] = "eventfd-count:";
+	static const char efd_id_pfx[] = "eventfd-id:";
+	static const char efd_semaphore_pfx[] = "eventfd-semaphore:";
+
+	uint64_t u = 5;
+	uint64_t efd_counter = u;
+	int efd_id = -1;
+	int efd_semaphore = 0;
+	pid_t pid = getpid();
+
+	struct fdinfo fdinfo_lines[] = {
+		{
+			.search_pfx = efd_counter_pfx,
+			.search_pfx_len = sizeof(efd_counter_pfx) - 1,
+			.avail = false,
+			.data = NULL
+		},
+		{
+			.search_pfx = efd_id_pfx,
+			.search_pfx_len = sizeof(efd_id_pfx) - 1,
+			.avail = false,
+			.data = (void *)&efd_id
+		},
+		{
+			.search_pfx = efd_semaphore_pfx,
+			.search_pfx_len = sizeof(efd_semaphore_pfx) - 1,
+			.avail = false,
+			.data = NULL
+		}
+	};
+
+	size_t fdinfo_array_size = ARRAY_SIZE(fdinfo_lines);
+
+	int efd = eventfd((unsigned int)u, 0);
+	if (efd == -1)
+		perror_msg_and_fail("eventfd");
+
+	procfs_check_avail_efd_data(pid, efd, fdinfo_lines, fdinfo_array_size);
+
+	printf("eventfd2(%d, 0) = %d", (unsigned int)u, efd);
+	print_eventfd_details(fdinfo_lines, fdinfo_array_size, efd_counter, efd_semaphore);
+	printf("\n");
+
+	uint64_t read_efd_count;
+	if (read(efd, &read_efd_count, sizeof(uint64_t)) == -1)
+		perror_msg_and_fail("read");
+	efd_counter -= read_efd_count;
+
+	int efd2 = dup(efd);
+
+	printf("dup(%d", efd);
+	print_eventfd_details(fdinfo_lines, fdinfo_array_size, efd_counter, efd_semaphore);
+	printf(") = %d", efd2);
+	print_eventfd_details(fdinfo_lines, fdinfo_array_size, efd_counter, efd_semaphore);
+	printf("\n");
+
+	uint64_t efd3_counter = u;
+	int efd3_id = -1;
+	int efd3_semaphore = 1;
+
+	fdinfo_lines[0].avail = false;
+	fdinfo_lines[1].avail = false;
+	fdinfo_lines[1].data = (void *)&efd3_id;
+	fdinfo_lines[2].avail = false;
+
+	int efd3 = eventfd((unsigned int)u, EFD_SEMAPHORE);
+	if (efd3 == -1)
+		perror_msg_and_fail("eventfd");
+
+	procfs_check_avail_efd_data(pid, efd3, fdinfo_lines, fdinfo_array_size);
+
+	printf("eventfd2(%d, EFD_SEMAPHORE) = %d", (unsigned int)u, efd3);
+	print_eventfd_details(fdinfo_lines, fdinfo_array_size, efd3_counter, efd3_semaphore);
+	printf("\n");
+
+	if (read(efd3, &read_efd_count, sizeof(uint64_t)) == -1)
+		perror_msg_and_fail("read");
+	efd3_counter -= read_efd_count;
+
+	int efd4 = dup(efd3);
+
+	printf("dup(%d", efd3);
+	print_eventfd_details(fdinfo_lines, fdinfo_array_size, efd3_counter, efd3_semaphore);
+	printf(") = %d", efd4);
+	print_eventfd_details(fdinfo_lines, fdinfo_array_size, efd3_counter, efd3_semaphore);
+	printf("\n");
+
+
+	close(efd);
+	close(efd2);
+	close(efd3);
+	close(efd4);
+	return 0;
+}
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 4cf303333..950b18b37 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -113,6 +113,7 @@ epoll_pwait2-P	--trace=epoll_pwait2 -P /dev/full
 epoll_pwait2-y	--trace=epoll_pwait2 -y
 epoll_wait	-a26
 erestartsys	-a34 -e signal=none -e trace=recvfrom
+eventfd-yy -a10 --trace=dup,eventfd2 -yy -qq
 execve--secontext	+execve.test --secontext
 execve--secontext_full	+execve.test --secontext=full
 execve--secontext_full_mismatch	+execve.test --secontext=full,mismatch
-- 
2.45.0



More information about the Strace-devel mailing list