I keep banging my head trying to get CI to work. I’m running my plugin via pluginval under Xorg or xvfb on Ubuntu 22.04. It bails out with:
X Error of failed request: BadAtom (invalid Atom parameter)
Major opcode of failed request: 18 (X_ChangeProperty)
Atom id in failed request: 0x0
Serial number of failed request: 71
Current serial number in output stream: 82
I’m not an expert on this topic, but it looks like Godot had similar issues — Atoms needed to be checked for existence before calling X_ChangeProperty.
I’m looking into pairing Xvfb/Xdummy with a window manager to see if that works around the issue…
Be careful that you’re misinterpreting the values returned from X_ChangeProperty - use error handlers after X_* calls to validate error state, and be aware that xlib functions return 1 most of the time - this can be misinterpreted as a ‘fail because not=0’, but its there because you’re expected to use error handlers to check state:
XLib can be a constant source of frustration if you forget that you are supposed to check things almost every step of the way and not rely on function-returned values…
Things seem happier with a window manager (fluxbox), but still not out of the woods…It does seem that JUCE’s XLib implementation would benefit from better error handling, as you described.
Thanks for reporting. I can reproduce a very similar issue on a full desktop environment, so having a headless installation seems to be incidental. The key for me was to use --validate-in-process parameter. I’m still trying to figure out what goes wrong exactly.
I managed to reproduce very similar crashes to this with a plugin that was creating a separate window of its own.
In my case the problem when running pluginval in command line was that the plugin would start calling Xlib functions before proper initialisation by the host. In particular it was missing the call to XInitThreads() that seemed to be the main culprit.
Xlib is initialised lazily to support use cases where X11 is not available. So I think it is the host’s responsibility to do explicit initialisation, when it knows that it’s about to do things that require it, such as opening a plugin that may use it.
A direct way of doing this would be adding the JUCE_GUI_BASICS_INCLUDE_XHEADERS=1 definition and calling juce::XWindowSystem::getInstance(). The extra includes however cause compile errors in pluginval, so a workaround is making a call that will certainly initialise Xlib.
Hey Attila, thanks so much for looking into this! You are awesome. I’m super appreciative that you went out of your way to check into pluginval, which isn’t even a part of JUCE core.
So I think it is the host’s responsibility to do explicit initialization, when it knows that it’s about to do things that require it, such as opening a plugin that may use it.
This sounds reasonable to me.
I’ll take a look to see if it resolves the issues here (I’m betting it will) and if so, I’ll submit a PR to pluginval.
Another delayed thank you to you @attila! I ended up resolving the compile errors and adding the JUCE_GUI_BASICS_INCLUDE_XHEADERS=1 — a perfect resolution and pluginval seems to finally be all the way happy on linux with Xvfb.