SYNC extension: misalignment of system counter structs?
Alan Coopersmith
alan.coopersmith at oracle.com
Thu Feb 6 20:15:07 UTC 2025
On 2/4/25 09:46, Daniel Neugebauer wrote:
> Hi,
>
> I've recently started using XCB for screen capture and was looking for a good
> way to wait for events with a timeout. I'm aware of the hack to monitor the
> socket/file descriptor but stumbled upon SYNC alarms based on SERVERTIME [1]
> which actually looks like the clean solution to eventually get unblocked if no
> other events arrive.
>
> Following that article, I tried to iterate over all system counters as returned
> by xcb_sync_list_system_counters but couldn't find SERVERTIME. This is odd, also
> "VICEIDLETIME" and empty counter names made no sense so I started looking into
> memory and noticed that XCB appears to have a misalignment when accessing/
> iterating over xcb_sync_systemcounter_t: Struct xcb_sync_systemcounter_t gets
> aligned to a length of 16 bytes but actually ends after 14 bytes, followed by
> the counter's name (explaining the missing 2 characters on [DE]VICEIDLETIME).
> This misalignment makes both xcb_sync_systemcounter_next and
> xcb_sync_systemcounter_name unusable.
>
> As I am compiling XCB myself for static linking, I wasn't sure if that's a local
> (self-induced) issue or a bug, so I tried to link dynamically against system
> libraries and also tried it on another system [2] but the issue seems to be
> present in all cases.
>
> Accessing the SYNC extension via XCB appears to be pretty rare, at least I
> couldn't find any prior implementations for reference when I googled it.
>
> I saw that events use a define XCB_PACKED and tried to apply that to the
> xcb_sync_systemcounter_t struct but the iterator then (still?) ends up
> miscalculating paddings (I end up 2 bytes past the struct).
>
> It would be great if someone could confirm the issue. See [3] for a test
> implementation incl. a local workaround. Is there anything I'm doing wrong on my
> end?
I can confirm - I did a quick port of the "-ext SYNC" code in xdpyinfo to use
libxcb-sync and saw that the first two characters of each system counter name
were cut off compared to the libXext version:
https://gitlab.freedesktop.org/alanc/xdpyinfo/-/commit/bbeefb9c236d2cfb005d05cd09ec7593d4b12ad9
Looking at the generated code it appears to be because the code to find the
start of the name is simply:
char *
xcb_sync_systemcounter_name (const xcb_sync_systemcounter_t *R)
{
return (char *) (R + 1);
}
and the xcb_sync_systemcounter_t struct has two bytes of padding automatically
inserted by the compiler. Adding __attribute__ ((__packed__)) to the
definition of the xcb_sync_systemcounter_t fixes it for the first counter,
but then breaks the alignment for finding the rest of the counters.
So while I can confirm, I don't know how to fix it.
--
-Alan Coopersmith- alan.coopersmith at oracle.com
Oracle Solaris Engineering - https://blogs.oracle.com/solaris
More information about the Xcb
mailing list