[PATCH] libwayland: Add WAYLAND_DEBUG_INTERFACES
wl at ongy.net
wl at ongy.net
Fri Jun 29 08:43:28 UTC 2018
From: Markus Ongyerth <wl at ongy.net>
Add environment variable WAYLAND_DEBUG_INTERFACES for filtering the
output of WAYLAND_DEBUG logs.
While WAYLAND_DEBUG is a pretty powerful and useful debug tool, printing
everything has a few downsides.
1) It's a full keylogger (getting debug-logs from users)
2) It can be overly spammy with wl_buffer/wl_surface actions (e.g. when
playing a video))
With this addition it's possible to supply another environment
variable, to filter on the interfaces one is interested in.
E.g. when interested in the behaviour of xdg-shell popups the filter could be
WAYLAND_DEBUG_INTERFACES=xdg_positioner,xdg_surface,xdg_popup
greatly improving SNR on the output and hiding potentially sensitive
information such as keystrokes.
---
src/wayland-client.c | 85 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 81 insertions(+), 4 deletions(-)
diff --git a/src/wayland-client.c b/src/wayland-client.c
index efeb745..9de8e4e 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -118,6 +118,31 @@ struct wl_display {
/** \endcond */
static int debug_client = 0;
+static size_t debug_client_count = 0;
+static char **debug_client_interfaces = NULL;
+
+static void
+wl_client_debug_print(struct wl_closure *closure,
+ struct wl_object *target, int send)
+{
+ if (debug_client_interfaces) {
+ bool found = false;
+ size_t i;
+ for (i = 0; i < debug_client_count; ++i) {
+ if (!strcmp(target->interface->name,
+ debug_client_interfaces[i])) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ return;
+ }
+ }
+
+ wl_closure_print(closure, target, send);
+}
/**
* This helper function wakes up all threads that are
@@ -748,7 +773,7 @@ wl_proxy_marshal_array_constructor_versioned(struct wl_proxy *proxy,
wl_abort("Error marshalling request: %s\n", strerror(errno));
if (debug_client)
- wl_closure_print(closure, &proxy->object, true);
+ wl_client_debug_print(closure, &proxy->object, true);
if (wl_closure_send(closure, proxy->display->connection))
wl_abort("Error sending request: %s\n", strerror(errno));
@@ -1016,6 +1041,56 @@ connect_to_socket(const char *name)
return fd;
}
+/* Set up the filter list for WAYLAND_DEBUG output.
+ * This reads WAYLAND_DEBUG_INTERFACEs and splits the provided string on every
+ * ','.
+ * The resulting list of strings is used as whitelist for interfaces printed by
+ * the WAYLAND_DEBUG mechanism.
+ * Sadly this leaks the memory required to strdup() the environment variable,
+ * but since this is a debug feature, and it should be constant over the
+ * lifetime of a single process, I consider it a minor problem
+ */
+static void
+setup_interface_filter(void)
+{
+ char *saveptr;
+ char *token;
+ size_t count = 0;
+ size_t i;
+ char *env;
+
+ /* We set this up before (on another wl_display_connect probably) so we
+ * don't have to do anything this time
+ */
+ if (debug_client_interfaces)
+ return;
+
+ if (!(env = getenv("WAYLAND_DEBUG_INTERFACES")))
+ return;
+
+ if (!(env = strdup(env))) {
+ wl_log("error: Could not allocate memory for WAYLAND_DEBUG_INTERFACES\n");
+ return;
+ }
+
+ for (i = 0; env[i]; ++i) {
+ if (env[i] == ',')
+ ++count;
+ }
+
+ /* The maximum possible interfaces is the number of ',' found + 1 */
+ debug_client_interfaces = calloc(count + 1, sizeof(char *));
+ if (!debug_client_interfaces) {
+ wl_log("error: Could not allocate memory for WAYLAND_DEBUG_INTERFACES\n");
+ free(env);
+ return;
+ }
+
+ for (token = strtok_r(env, ",", &saveptr); token; token = strtok_r(NULL, ",", &saveptr)) {
+ debug_client_interfaces[debug_client_count++] = token;
+ }
+}
+
/** Connect to Wayland display on an already open fd
*
* \param fd The fd to use for the connection
@@ -1034,8 +1109,10 @@ wl_display_connect_to_fd(int fd)
const char *debug;
debug = getenv("WAYLAND_DEBUG");
- if (debug && (strstr(debug, "client") || strstr(debug, "1")))
+ if (debug && (strstr(debug, "client") || strstr(debug, "1"))) {
debug_client = 1;
+ setup_interface_filter();
+ }
display = zalloc(sizeof *display);
if (display == NULL) {
@@ -1423,13 +1500,13 @@ dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
if (proxy->dispatcher) {
if (debug_client)
- wl_closure_print(closure, &proxy->object, false);
+ wl_client_debug_print(closure, &proxy->object, false);
wl_closure_dispatch(closure, proxy->dispatcher,
&proxy->object, opcode);
} else if (proxy->object.implementation) {
if (debug_client)
- wl_closure_print(closure, &proxy->object, false);
+ wl_client_debug_print(closure, &proxy->object, false);
wl_closure_invoke(closure, WL_CLOSURE_INVOKE_CLIENT,
&proxy->object, opcode, proxy->user_data);
--
2.18.0
More information about the wayland-devel
mailing list