How to use wl_object in wl_protocol_logger API?

Chloe Pelling cpelling at google.com
Thu May 2 01:07:41 UTC 2024


I found a solution, but my offer to send a pull request adding
wl_object_get_class() and wl_object_get_id() still stands. Let me know!

To recap, my key question was: "The wl_protocol_logger API exposes a
wl_object struct. How can I get the object class and ID from a wl_object?"

To answer my own question: wl_object is actually declared here, behind an
#ifndef:
https://gitlab.freedesktop.org/wayland/wayland/-/blob/69633202180acce9d0d5ab4037d80291c71b2307/src/wayland-server.h#L58

The declaration is deprecated, though. I'm using it anyway for now, but I
think accessor functions would be better so that I can treat wl_object as
opaque. I'm happy to contribute if desired.

Best regards,
Chloe

On Tue, Apr 16, 2024 at 10:56 AM Chloe Pelling <cpelling at google.com> wrote:

> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20240502/69ce4286/attachment.htm>


More information about the wayland-devel mailing list