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