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