[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