How to use wl_object in wl_protocol_logger API?

Chloe Pelling cpelling at google.com
Tue Apr 16 00:56:25 UTC 2024


Hi,

I'm attempting to use the wl_protocol_logger API to replicate the
functionality of WAYLAND_DEBUG=1 in my project, but logging to
https://perfetto.dev/ rather than stderr. I'm having some trouble
decoding message arguments of type object, since `wl_object` is an
opaque struct and there doesn't appear to be a "blessed" way to
interrogate it. In particular, there's no API to access
`wl_object::id`.

Am I missing something? Would a patch adding wl_object_get_id() and
wl_object_get_class() functions be welcome?

Here's what I've figured out so far:

* Decoding the arguments requires inspecting the wl_argument unions in
`wl_protocol_logger_message::arguments`, according to the type
indications in `wl_protocol_logger_message::message->signature`.

* Object arguments are denoted by "o" in the signature, indicating we
should examine `wl_argument::o` of type wl_object.

* wl_object is an opaque struct, and there are no
wl_object_get_class() or wl_object_get_id() functions.

* I can work around the lack of wl_object_get_class() by inspecting
wl_protocol_logger_message::message->types[i] for argument
wl_protocol_logger_message::arguments[i]. However, no such workaround
exists to retrieve the wl_object's id.

* https://github.com/KDAB/GammaRay works around this problem by
casting wl_argument::o to wl_resource* and using
wl_resource_get_class() and wl_resource_get_id().

    * This works because wl_resource's first member is wl_object, and
wl_resource_get_class() and wl_resource_get_id() are implemented only
by accessing that first member.
    *  While comments in wl_resource indicate that the struct layout
cannot be changed. It's unclear if that will be true forever.
    * There is no guarantee that wl_resource_get_class() and
wl_resource_get_id() won't start accessing members of wl_resource
other than `object`. If they did, this technique could cause invalid
memory access due to overflowing the size of wl_object.

I believe these are my current options:

A) Cast wl_object* to wl_resource* like GammaRay does. I'm
uncomfortable with this, for the reasons above.

B) Copy the definition of `struct wl_object` from wayland-private.h
into my project and access `id` directly. This might be safer than (A)
in practice, but I still don't like it.

C) Submit a patch adding wl_object_get_class() and wl_object_get_id()
accessor functions.

Have I missed something? Any advice would be helpful.

Best regards,
Chloe


More information about the wayland-devel mailing list