[PATCH i-g-t 28/28] sigsafe logging and static asserts for sizes and offsets

Petri Latvala petri.latvala at intel.com
Mon Mar 22 11:34:20 UTC 2021


---
 lib/igt_core.c    | 10 ++++++++--
 lib/runnercomms.c | 27 ++++++++++++++++++++++++++-
 lib/runnercomms.h | 23 +++++++++++++++++++++--
 3 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/lib/igt_core.c b/lib/igt_core.c
index beb2dade..1f4edb44 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -1811,7 +1811,10 @@ static bool running_under_gdb(void)
 
 static void __write_stderr(const char *str, size_t len)
 {
-	igt_ignore_warn(write(STDERR_FILENO, str, len));
+	if (runner_connected())
+		log_to_runner_sig_safe(str, len);
+	else
+		igt_ignore_warn(write(STDERR_FILENO, str, len));
 }
 
 static void write_stderr(const char *str)
@@ -1885,7 +1888,10 @@ static const char hex[] = "0123456789abcdef";
 static void
 xputch(int c)
 {
-	igt_ignore_warn(write(STDERR_FILENO, (const void *) &c, 1));
+	if (runner_connected())
+		log_to_runner_sig_safe((const void *) &c, 1);
+	else
+		igt_ignore_warn(write(STDERR_FILENO, (const void *) &c, 1));
 }
 
 static int
diff --git a/lib/runnercomms.c b/lib/runnercomms.c
index 5588b63c..e5db5127 100644
--- a/lib/runnercomms.c
+++ b/lib/runnercomms.c
@@ -22,6 +22,7 @@
  */
 
 #include <assert.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
@@ -42,7 +43,7 @@
  * shortcomings and pain points of text-based communication.
  */
 
-static int runner_socket_fd = -1;
+static sig_atomic_t runner_socket_fd = -1;
 
 /**
  * set_runner_socket:
@@ -480,3 +481,27 @@ uint32_t socket_dump_canary(void)
 {
 	return 'I' << 24 | 'G' << 16 | 'T' << 8 | '1';
 }
+
+void log_to_runner_sig_safe(const char *str, size_t len)
+{
+	size_t prlen = len;
+
+	struct runnerpacket_log_sig_safe p = {
+					      .size = sizeof(struct runnerpacket) + sizeof(uint8_t),
+					      .type = PACKETTYPE_LOG,
+					      .senderpid = getpid(),
+					      .sendertid = 0, /* gettid() not signal safe */
+					      .stream = STDERR_FILENO,
+	};
+
+	if (len > sizeof(p.data) - 1)
+		prlen = sizeof(p.data) - 1;
+	memcpy(p.data, str, prlen);
+	p.size += prlen + 1;
+
+	write(runner_socket_fd, &p, p.size);
+
+	len -= prlen;
+	if (len)
+		log_to_runner_sig_safe(str + prlen, len);
+}
diff --git a/lib/runnercomms.h b/lib/runnercomms.h
index d322039d..cc7d78f6 100644
--- a/lib/runnercomms.h
+++ b/lib/runnercomms.h
@@ -24,14 +24,15 @@
 #ifndef IGT_RUNNERCOMMS_H
 #define IGT_RUNNERCOMMS_H
 
-#include <stdint.h>
 #include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
 
 /*
  * A flat struct that can and will be directly dumped to
  * disk. Constructed with runnerpacket_<type>() helper functions.
  */
-struct runnerpacket {
+struct __attribute__((packed)) runnerpacket {
 	uint32_t size; /* Full size of the packet in octets */
 	uint32_t type; /* runnerpacket_type, but fixed width */
 	int32_t senderpid;
@@ -40,6 +41,9 @@ struct runnerpacket {
 	char data[];
 };
 
+_Static_assert(sizeof(struct runnerpacket) == 4 * 4, "runnerpacket structure must not change");
+_Static_assert(offsetof(struct runnerpacket, data) == 4 * 4, "runnerpacket structure must not change");
+
 /*
  * A helper for reading and parsing runnerpacket structs. Fields will
  * point directly into the data field of an existing runnerpacket
@@ -222,4 +226,19 @@ struct runnerpacket *runnerpacket_resultoverride(const char *result);
 
 uint32_t socket_dump_canary(void);
 
+struct __attribute__((packed)) runnerpacket_log_sig_safe {
+	uint32_t size;
+	uint32_t type;
+	int32_t senderpid;
+	int32_t sendertid;
+
+	uint8_t stream;
+	char data[128];
+};
+
+_Static_assert(offsetof(struct runnerpacket_log_sig_safe, stream) == 4 * 4, "signal-safe log runnerpacket must be compatible");
+_Static_assert(offsetof(struct runnerpacket_log_sig_safe, data) == 4 * 4 + 1, "signal-safe log runnerpacket must be compatible");
+
+void log_to_runner_sig_safe(const char *str, size_t len);
+
 #endif
-- 
2.29.2



More information about the Intel-gfx-trybot mailing list