[SOLVED] X11Symbols singleton memory leaks

I’m getting a bunch of memory leaks in X11Symbols and DynamicLibrary objects if i early exit a JUCEApplication on linux without X11. Just making the X11Symbols singleton inherit from DeletedAtShutdown is making them go away.

Any way to get this sorted out ?

Also, is there a way to know if x11 is available ? X11Symbols::areXFunctionsAvailable would do the trick, but is a private class so i need to modify the juce source code to expose it.

We need to have a bit more control over when the X11Symbols singleton is deleted which is why it doesn’t inherit from DeletedAtShutdown. It should be getting cleaned up in the destructor of the window system regardless of whether X11 is available or not though. How are you quitting the application when the leaks occur?

Exposing X11Symbols isn’t something we want to do as that’s an internal class. What’s your use case for needing to know if X11 is available?

I’ve checked the code and indeed X11Symbols instance should be cleared at the XWindowSystem destructor, but that is only if you have X11, you probably want to move X11Symbols::deleteInstance outside of the if clause:

XWindowSystem::~XWindowSystem()
{
    if (xIsAvailable)
    {
        destroyXDisplay();

        if (JUCEApplicationBase::isStandaloneApp())
            X11ErrorHandling::removeXErrorHandlers();

        X11Symbols::deleteInstance(); // < Should move this outside of the if, or you'll leak it
    }

    clearSingletonInstance();
}

In the JUCEApplication::initialise i create a juce DocumentWindow, but if i don’t have X11, then i get annoying asserts in Juce XWindowing code, so i should be able to say:

class MyApp : public JUCEApplication
{
    void initialise()
    {
        if (JUCEApplicationBase::isHeadlessApplication())
            return;
    
        mainWindow = std::make_unique<MyWindow>();
    }
};

I tried looking into using Displays or Desktop to query if i have displays or desktops, but i always get asserts in a docker without X11.

Are you on the latest version of JUCE? That has been fixed for a while. I believe it was even fixed prior to the JUCE 6 release so if you’re still on the technical preview branch you should definitely upgrade as there have been numerous other fixes.

Adding something like that to JUCEApplication seems sensible. We’ll take a look.

Yeah indeed i’m in an old branch from juce6, and this is fixed upstream. Will try to bump but as i have a lot of custom improvements to juce it will take some time…

Ideally, having a Displays::getNumAvailableDisplays() returning 0 available displays when run without x11 should be a better API

Is this a sensible addition ?

Array<Displays::Display> XWindowSystem::findDisplays (float masterScale) const
{
    Array<Displays::Display> displays;

    if (! xIsAvailable)                 // <<
        return displays;                // <<

This way i could use juce::Desktop::getInstance().getDisplays().displays.size() (!?! not really a nice api tho…) to know if i have a main display. Strange that Displays::getMainDisplay() returns a reference… what if we have no main display ?

There are a few commits to address this on develop now. You can call instantiate the Desktop singleton without it throwing assertions on a headless system and there is also a new Desktop::isHeadless() convenience method which you can use to check if there are any valid connected displays. A few of the old Displays methods which returned a const-ref to a Display object have been deprecated and replaced with methods returning a pointer, so you can check for nullptr on headless systems.

Amazing! Thanks a lot