pierreguillot / Camomile

An audio plugin with Pure Data embedded that allows to load and to control patches
GNU General Public License v3.0
913 stars 65 forks source link

Multiple instances of lv2 camomile freezes reaper and carla on 32 bit linux mint 19. #286

Open TheGuyWhoo opened 3 years ago

TheGuyWhoo commented 3 years ago

(in the plugin by distrho called ildaeli when I enable 'run in bridge mode' I am able to load multiple instances. Also in reaper when I run carla as dedicated process I am able to load multiple instances)

Whether or not the same issue is present in vst3 idk because those don't load at all but I'll make a separate issue for that. It happens in Carla and reaper, both latest versions on 32 bit linux mint 19. it happens wirh all plugins generated through camomile. Multiple instances of the same plugin does not cause this issue. Carla freezes before it logs anything about the second instance, but here's a log anyway:

======= Starting engine =======
======= Engine started ========
Carla engine started, details:
  Driver name:  JACK
  Sample rate:  44100
  Process mode: Continuous Rack
verbose(4): input channels = 2, output channels = 2

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.change.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.change.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.change.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.change/param.change.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.change/param.change.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.change/param.change.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.change.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.change.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/overdrive~.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/overdrive~.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/overdrive~.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/overdrive~/overdrive~.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/overdrive~/overdrive~.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/overdrive~/overdrive~.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/overdrive~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/overdrive~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/leslie~.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/leslie~.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/leslie~.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/leslie~/leslie~.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/leslie~/leslie~.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/leslie~/leslie~.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/leslie~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/leslie~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/volume~.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/volume~.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/volume~.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/volume~/volume~.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/volume~/volume~.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/volume~/volume~.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/volume~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/volume~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link/gui.link.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link/gui.link.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link/gui.link.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set/param.set.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set/param.set.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set/param.set.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get/param.get.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get/param.get.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get/param.get.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link/midi.ctrl.link.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link/midi.ctrl.link.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link/midi.ctrl.link.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/midi.ctrl.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/gui.link.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/param.get.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/program.manager.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/program.manager.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/program.manager.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/program.manager/program.manager.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/program.manager/program.manager.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/program.manager/program.manager.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/program.manager.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/program.manager.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.fill.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.fill.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.fill.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.fill/harmonic.fill.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.fill/harmonic.fill.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.fill/harmonic.fill.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.fill.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.fill.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set/harmonic.set.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set/harmonic.set.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set/harmonic.set.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.fill.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/harmonic.set.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~/voice~.l_i386 and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~/voice~.pd_linux and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~/voice~.so and failed

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): tried /usr/lib/lv2/AlmondOrgan.lv2/voice~.pd and succeeded

verbose(4): input channels = 0, output channels = 2

verbose(4): input channels = 0, output channels = 2
hyperpenelope commented 2 years ago

I am also seeing the same problem with Ardour: two instances of the same Camomile LV2 plugin will work fine, but having two different Camomile plugins causes Ardour to hang.

Environment

OS: Debian 11
Architecture: amd64
DAW: Ardour 6.7.0
Camomile version: v1.0.8-beta10

Some debug output from Ardour

I had a project in Ardour which already used an instance of AlmondOrgan (LV2). That works well. When I add an instance of the Castafiore effect (also LV2) to an audio track, Ardour freezes/hangs. At the same time, Ardour's terminal output is filled with thousands of repetitions of this message:

JUCE Assertion failure in juce_MessageManager.cpp:310

Basic investigation: what assertion is failing?

The error message refers to this part of Juce/modules/juce_events/messages/juce_MessageManager.cpp:

bool MessageManager::Lock::tryAcquire (bool lockIsMandatory) const noexcept
{
    auto* mm = MessageManager::instance;

    if (mm == nullptr)
    {
        jassertfalse;
        return false;
    }
...
}

I don't know the JUCE code well, but the following around line 420 is suspicious. It loops over (a wrapper method of) the tryAcquire method.

bool MessageManagerLock::attemptLock (Thread* threadToCheck, ThreadPoolJob* jobToCheck)
{
...
    // tryEnter may have a spurious abort (return false) so keep checking the condition
    while ((threadToCheck == nullptr || ! threadToCheck->threadShouldExit())
             && (jobToCheck == nullptr || ! jobToCheck->shouldExit()))
    {
        if (mmLock.tryEnter())
            break;
    }
...
}

Any ideas or comments would be appreciated because I'd like to get this bug fixed!

hyperpenelope commented 2 years ago

I added a few lines of debugging code to the attemptLock() method mentioned in my previous comment. This confirmed that the infinite loop of assertion failures is happening in the while loop which I quoted.

Making use of backtrace, I also obtained a stack-trace showing (sort of) how attemptLock() is being called:

backtrace returned 31 function calls
/usr/local/lib/lv2/Castafiore.lv2/Castafiore.so(_ZN4juce18MessageManagerLock11attemptLockEPNS_6ThreadEPNS_13ThreadPoolJobE+0x5f)
/usr/local/lib/lv2/Castafiore.lv2/Castafiore.so(_ZN4juce18MessageManagerLockC1EPNS_6ThreadE+0x57)
/usr/local/lib/lv2/Castafiore.lv2/Castafiore.so(_ZN14JuceLv2WrapperC2EdPKPK11LV2_Feature+0x2be) 
/usr/local/lib/lv2/Castafiore.lv2/Castafiore.so(+0x6c9d0d) 
/opt/Ardour-6.7.0/lib/liblilv-0.so.0(lilv_plugin_instantiate+0x183)
... stack-trace continues with more functions in Ardour code ...

This shows that, when an LV2 plugin is initialised, a JuceLv2Wrapper object is constructed, and this leads to attemptLock() being called. At the top of the constructor function (see LV2/juce_LV2_Wrapper.cpp around line 727), a MessageManagerLock is declared:

        {
            const MessageManagerLock mmLock;
            filter = std::unique_ptr<AudioProcessor>(createPluginFilterOfType (AudioProcessor::wrapperType_LV2));
        }

My debugging suggests that, when a second Camomile plugin is initialised by the DAW, the construction of the JuceLv2Wrapper never gets past this section of code. While it is trying to construct mmLock, the tryEnter() method is called repeatedly on the lock in a loop but it fails continuously on the assertion.

hyperpenelope commented 2 years ago

Here is how (I think) the MessageManager is created for an LV2 plugin.

Around line 1500 of LV2/juce_LV2_Wrapper.cpp, in the definition of the class JuceLv2Wrapper:

private:
#if JUCE_LINUX
    SharedResourcePointer<SharedMessageThread> msgThread;
#else
    SharedResourcePointer<ScopedJuceInitialiser_GUI> sharedJuceGUI;
#endif

That SharedMessageThread object, when constructed, should call its own run() method, which will create a MessageManager provided one doesn't already exist via the getInstance() method.

struct SharedMessageThread  : public Thread
{
    void run() override
    {
// ...
        MessageManager::getInstance()->setCurrentThreadAsMessageThread();
// ...
        while ((! threadShouldExit()) && MessageManager::getInstance()->runDispatchLoopUntil (250))
        {}
    }
}

Debugging shows that:

Despite the fact that all plugin instances share the SharedMessageThread, the MessageManager instance cannot be found by the second plugin instance - calling MessageManager::getInstanceWithoutCreating() will return 0. This, in turn, causes an assertion in the JUCE code to be true when it is required to be false. JUCE just cranks the assertion again and again in a loop, causing the plugin and DAW to hang.

A question

What I don't know is this: should the MessageManager be shared across all instances of Camomile plugins? At the moment, it is shared across instances of the same plugin, but not across instances of two different plugins. @pierreguillot do you have a view? Not a relevant question now.

hyperpenelope commented 2 years ago

I have found a fix, but not the fix...

I changed line 133 of CMakeLists.txt to specify the latest C++ standard:

-set_target_properties(Camomile_LV2 PROPERTIES PREFIX "")
+set_target_properties(Camomile_LV2 PROPERTIES PREFIX "" CXX_STANDARD 20)

and made the SharedMessageThread...well...not shared! The change applies to LV2/juce_LV2_Wrapper.cpp:

-    SharedResourcePointer<SharedMessageThread> msgThread;
+    SharedMessageThread msgThread;

Multiple different Camomile plugins can now be loaded, and the plugins are working. Once, when I closed my Ardour session after inserting and deleting multiple Camomile plugins, it froze, but since then I have worked on the session several times and it has always closed without issue.

hyperpenelope commented 2 years ago

After trying a few things out, I've discovered that a message thread created via SharedResourcePointer is actually shared across all instances of any Camomile plugin. Let's say I have a Bulgroz instance loaded already. I have verified that, when a Castafiore instance is loaded, it begins constructing a SharedResourcePointer<SharedMessageThread> but stops because it finds that there is already a SharedResourcePointer of that type - namely the one created when Bulgroz was loaded.

This seems really odd to me...I would have expected a SharedResourcePointer to be shared across instances of the same plugin, but it is somehow being shared across all instances of all Camomile plugins.

How is it being shared? Well...

$ objdump -T ./Plugins/builds/Castafiore.lv2/Castafiore.so | grep 'getSharedObjectHolder'
00000000006cc3c3  w   DF .text  000000000000000d  Base        _ZN4juce21SharedResourcePointerI19SharedMessageThreadE21getSharedObjectHolderEv
000000000111d980 u    DO .bss   0000000000000018  Base        _ZZN4juce21SharedResourcePointerI19SharedMessageThreadE21getSharedObjectHolderEvE6holder

The second line of output seems to refer to a variable in a method of the SharedResourcePointer class. The u signifies that this is a unique global symbol. According to the man-page for objdump:

Unique global symbols are a GNU extension to the standard set of ELF symbol bindings. For such a symbol the dynamic linker will make sure that in the entire process there is just one symbol with this name and type in use.

That explains it - this "holder", which keeps track of the object held by the SharedResourcePointer, will have the same value throughout the entire process - meaning the whole of Ardour?

The question now is: why the fu-...I mean, how did this end up being "unique global", and can this be changed?

hyperpenelope commented 2 years ago

It wasn't easy to find, but this GCC bug report seems to be the final piece in the puzzle: Problem with C++ unique symbols in plugins

The answer is that specifying -fno-gnu-unique as an option to GCC will disable the marking of symbols as "unique global".

Raising a PR.

pierreguillot commented 1 year ago

I guess this is fixed, isn't it?