[RFC PATCH v3 3/5] Add eventfd option to --decode-fds

Sahil Siddiq icegambit91 at gmail.com
Fri May 10 05:14:09 UTC 2024


Having an eventfd option for --decode-fds will help
examine the eventfd counter associated with an eventfd
file descriptor.

* src/filter_qualify.c
  (decode_fd_str_to_uint): Add "eventfd" option.
* src/number_set.h: Add DECODE_FD_EVENTFD.
* src/strace.c: Add "eventfd" option.
* src/util.c: Parse eventfd related details.

Signed-off-by: Sahil Siddiq <icegambit91 at gmail.com>
---
Changes v2 -> v3:
- src/util.c:
  (parse_fdinfo_efd_semaphore): New function.
  (parse_fdinfo_efd_counter): Treat efd_counter as string.
  (printeventfd): Refactor to use "struct fdinfo".

 src/filter_qualify.c |   1 +
 src/number_set.h     |   1 +
 src/strace.c         |   3 +-
 src/util.c           | 112 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/src/filter_qualify.c b/src/filter_qualify.c
index 87c1a6106..a79045468 100644
--- a/src/filter_qualify.c
+++ b/src/filter_qualify.c
@@ -105,6 +105,7 @@ decode_fd_str_to_uint(const char *str)
 		{ DECODE_FD_PATH,      "path" },
 		{ DECODE_FD_SOCKET,    "socket" },
 		{ DECODE_FD_DEV,       "dev" },
+		{ DECODE_FD_EVENTFD,   "eventfd" },
 		{ DECODE_FD_PIDFD,     "pidfd" },
 		{ DECODE_FD_SIGNALFD,  "signalfd" },
 	};
diff --git a/src/number_set.h b/src/number_set.h
index 0ce2b2db6..d28ac0cdd 100644
--- a/src/number_set.h
+++ b/src/number_set.h
@@ -75,6 +75,7 @@ enum decode_fd_bits {
 	DECODE_FD_PATH,
 	DECODE_FD_SOCKET,
 	DECODE_FD_DEV,
+	DECODE_FD_EVENTFD,
 	DECODE_FD_PIDFD,
 	DECODE_FD_SIGNALFD,
 
diff --git a/src/strace.c b/src/strace.c
index c5c9728aa..eea058f07 100644
--- a/src/strace.c
+++ b/src/strace.c
@@ -379,7 +379,8 @@ Output format:\n\
                  print exit reason of kvm vcpu\n\
   -e decode-fds=SET, --decode-fds=SET\n\
                  what kinds of file descriptor information details to decode\n\
-     details:    dev (device major/minor for block/char device files)\n\
+     details:    dev (device major/minor for block/char device files),\n\
+                 eventfd (associated eventfd object details for eventfds),\n\
                  path (file path),\n\
                  pidfd (associated PID for pidfds),\n\
                  socket (protocol-specific information for socket descriptors),\n\
diff --git a/src/util.c b/src/util.c
index f558d342c..2408664a8 100644
--- a/src/util.c
+++ b/src/util.c
@@ -895,6 +895,115 @@ printsignalfd(pid_t pid_of_fd, int fd, const char *path)
 	return scan_fdinfo(pid_of_fd, fd, fdinfo_lines, ARRAY_SIZE(fdinfo_lines));
 }
 
+static bool
+parse_fdinfo_efd_semaphore(const char *value, void *data)
+{
+	int *efd_semaphore = data;
+	*efd_semaphore = string_to_uint_ex(value, NULL, INT_MAX, "\n", 10);
+	return true;
+}
+
+static bool
+parse_fdinfo_efd_id(const char *value, void *data)
+{
+	int *efd_id = data;
+	*efd_id = string_to_uint_ex(value, NULL, INT_MAX, "\n", 10);
+	return true;
+}
+
+static bool
+parse_fdinfo_efd_counter(const char *value, void *data)
+{
+	char *ptr = (char *)value;
+	size_t len = strlen(ptr);
+
+	/*
+	 * Strip trailing newlines.
+	 */
+	for (; len > 0; --len) {
+		if (ptr[len - 1] != '\n')
+			break;
+	}
+	ptr[len] = '\0';
+
+	/*
+	 * Strip leading whitespace.
+	 */
+	while (*ptr != '\0' && (*ptr == ' ' || (unsigned int)(*ptr - 9) <= 4))
+		++ptr;
+
+	if (*ptr == '\0')
+		ptr = NULL;
+
+	*(char **)data = ptr;
+	return true;
+}
+
+static bool
+printeventfd(pid_t pid_of_fd, int fd, const char *path)
+{
+	static const char eventfd_path[] = "anon_inode:[eventfd]";
+	static const char efd_counter_pfx[] = "eventfd-count:";
+	static const char efd_id_pfx[] = "eventfd-id:";
+	static const char efd_semaphore_pfx[] = "eventfd-semaphore:";
+
+	if (strcmp(path, eventfd_path))
+		return false;
+
+	char *efd_counter = NULL;
+	int efd_id = -1;
+	int efd_semaphore = -1;
+
+	struct fdinfo fdinfo_lines[] = {
+		{
+			.search_pfx = efd_counter_pfx,
+			.search_pfx_len = sizeof(efd_counter_pfx) - 1,
+			.fn = parse_fdinfo_efd_counter,
+			.data = &efd_counter
+		},
+		{
+			.search_pfx = efd_id_pfx,
+			.search_pfx_len = sizeof(efd_id_pfx) - 1,
+			.fn = parse_fdinfo_efd_id,
+			.data = &efd_id
+		},
+		{
+			.search_pfx = efd_semaphore_pfx,
+			.search_pfx_len = sizeof(efd_semaphore_pfx) - 1,
+			.fn = parse_fdinfo_efd_semaphore,
+			.data = &efd_semaphore
+		}
+	};
+
+	scan_fdinfo(pid_of_fd, fd, fdinfo_lines, ARRAY_SIZE(fdinfo_lines));
+
+	if (efd_counter) {
+		tprint_associated_info_begin();
+		tprint_struct_begin();
+		tprints_field_name("eventfd-count");
+		tprints_string("0x");
+		tprints_string(efd_counter);
+
+		if (efd_id != -1) {
+			tprint_struct_next();
+			tprints_field_name("eventfd-id");
+			PRINT_VAL_U(efd_id);
+
+			if (efd_semaphore != -1) {
+				tprint_struct_next();
+				tprints_field_name("eventfd-semaphore");
+				PRINT_VAL_U(efd_semaphore);
+			}
+		}
+
+		tprint_struct_end();
+		tprint_associated_info_end();
+	} else
+		print_string_in_angle_brackets(path);
+
+	return true;
+}
+
 static void
 print_quoted_string_in_angle_brackets(const char *str, const bool deleted)
 {
@@ -923,6 +1032,9 @@ printfd_pid_with_finfo(struct tcb *tcp, pid_t pid, int fd, const struct finfo *f
 		if (is_number_in_set(DECODE_FD_DEV, decode_fd_set) &&
 		    printdev(tcp, fd, path, finfo))
 			goto printed;
+		if (is_number_in_set(DECODE_FD_EVENTFD, decode_fd_set) &&
+		    printeventfd(pid, fd, path))
+			goto printed;
 		if (is_number_in_set(DECODE_FD_PIDFD, decode_fd_set) &&
 		    printpidfd(pid, fd, path))
 			goto printed;
-- 
2.45.0



More information about the Strace-devel mailing list