[PATCH] libwayland: Add WAYLAND_DEBUG_INTERFACES

Markus Ongyerth wl at ongy.net
Fri Jun 29 08:46:16 UTC 2018


Urgh, of course I forget to mention something when I write mails.

This is current RFC quality, not actual patch. Should this be something people 
are interested in, I think it should live mostly in connection.c and be 
supported by both -server and -client libraries.

I'm also not sure whether the supplied whitelist approach is the best way to 
go, or this should be a blacklist in practice.

On 2018/6月/29 10:43, wl at ongy.net wrote:
> 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
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20180629/b9c43a06/attachment.sig>


More information about the wayland-devel mailing list