AudioPluginDemo is crashing Dorico 3.5.12

In order to reproduce, start a new empty project in Dorico, on macOS. Click on the ‘Play’ button in Dorico (upper left corner), click on the ‘+’ button in the ‘VST Instruments’ pane on the right of the interface , add AudioPluginDemo twice.

Save the project, close it. Quit dorico, restart Dorico load the project a few times, the crash happens very quickly here. With AudioPluginDemo (build on latest develop JUCE branch) the call stack do not show much:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   com.steinberg.vst3.vstaudioengine	0x000000010d81d22b 0x10d2cc000 + 5575211
1   com.steinberg.vst3.vstaudioengine	0x000000010d90e6e5 0x10d2cc000 + 6563557
2   com.steinberg.vst3.vstaudioengine	0x000000010d90e635 0x10d2cc000 + 6563381

However with my plugin, the crash happens inside the vst3 wrapper:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   ???                           	0x00007f958bd5c570 0 + 140280272897392
1   com.foo.MyPlugin. VST3	0x000000010f2c0001 juce::JucePluginFactory::release() + 33 (juce_VST3_Wrapper.cpp:3530)

With an older version of AudioPluginDemo based on juce 6.0.7, I got:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   ???                           	0x0000000000000001 0 + 1
1   com.JUCE.AudioPluginDemo      	0x0000000110e29e91 juce::ComSmartPtr<Steinberg::Vst::IHostApplication>::~ComSmartPtr() + 49
2   com.JUCE.AudioPluginDemo      	0x0000000110e29dd5 juce::ComSmartPtr<Steinberg::Vst::IHostApplication>::~ComSmartPtr() + 21
3   com.JUCE.AudioPluginDemo      	0x0000000110e29f10 juce::JucePluginFactory::~JucePluginFactory() + 96
4   com.JUCE.AudioPluginDemo      	0x0000000110e28f45 juce::JucePluginFactory::~JucePluginFactory() + 21
5   com.JUCE.AudioPluginDemo      	0x0000000110e28f6c juce::JucePluginFactory::~JucePluginFactory() + 28
6   com.JUCE.AudioPluginDemo      	0x0000000110e2890e juce::JucePluginFactory::release() + 78

I’m unable to repro this on the very latest develop (73523cd, Dorico 3.5.12, macOS 10.15.7).

The crashes you’re seeing look like they might be caused by a refcounting bug. There was a short window of time between the 13th of May (52e6c4f) and the 21st of May (2f04d6a8) where JUCE was incorrectly doing manual refcounting on a smart pointer in one of the VST3 SDK classes. If you were using a custom version of the VST3 SDK with a copy of JUCE from before the 21st of May, there’s a chance you may have run into the same issue. Are you able to reproduce the issue with a copy of JUCE from after the 21st of May?

Yes I still can reproduce it with develop 73523cd , Dorico 3.5.12, macOS 10.15.7. The stack trace I am now getting is this one:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   com.JUCE.AudioPluginDemo      	0x00000001101d8cd8 juce::VSTComSmartPtr<Steinberg::Vst::IHostApplication>::~VSTComSmartPtr() + 40 (juce_VST3Common.h:367)
1   com.JUCE.AudioPluginDemo      	0x00000001101d8c25 juce::VSTComSmartPtr<Steinberg::Vst::IHostApplication>::~VSTComSmartPtr() + 21 (juce_VST3Common.h:367)
2   com.JUCE.AudioPluginDemo      	0x00000001101d8d60 juce::JucePluginFactory::~JucePluginFactory() + 96 (juce_VST3_Wrapper.cpp:3474)
3   com.JUCE.AudioPluginDemo      	0x00000001101d7d95 juce::JucePluginFactory::~JucePluginFactory() + 21 (juce_VST3_Wrapper.cpp:3474)
4   com.JUCE.AudioPluginDemo      	0x00000001101d7dbc juce::JucePluginFactory::~JucePluginFactory() + 28 (juce_VST3_Wrapper.cpp:3471)
5   com.JUCE.AudioPluginDemo      	0x00000001101d775e juce::JucePluginFactory::release() + 78 (juce_VST3_Wrapper.cpp:3494)
6   com.steinberg.vst3.vstaudioengine	0x00000001041c726a 0x103b53000 + 6767210

Maybe I can send you my Dorico project (it contains only two instances of AudioPluginDemo). Just opening it and closing dorico triggers the crash.

I’d like to try debugging your project file, if you could send me a copy.

Edit: Sorry, just tried again and I can repro it now! I’ll investigate and update this thread if I find a fix.

FYI, the issue is still there with Dorico 5 and JUCE 7. It seems also very similar to Wavelab 10 crash on quit inside VST3 wrapper - #6 by pflugshaupt . I’m trying the following workaround which seems to avoid the crash:

add this method to VstComSmartPtr:

void forget() { source = nullptr; }

and call it in the JucePluginFactory destructor:

host.forget();

I guess the crash happens because Dorico destroys the host pointer before the JucePluginFactory is destroyed

May I also bring up this topic again @reuk ?
As user jpo already mentioned, in the Dorico 5area I also see this crash on quit bug. Here is an example stack:

0   Symbol was not found (0   com.hofa.IQReverb                 0x000000011dda7ca3 juce::JucePluginFactory::~JucePluginFactory() + 147)
1   Symbol was not found (1   com.hofa.IQReverb                 0x000000011dda74c0 juce::JucePluginFactory::release() + 32)
2   Steinberg::FModule::onUnload()
          defined in: ...890/b/lib.frame-base/source/module/fmodule.cpp:643
    line table: lib.frame-base/source/module/fmodule.cpp:648 (start line: 643)
3   ?
    additional inline call: Steinberg::FModuleBase::getProcAddress(char const*)
          caller:     /Users/buildserver/Builddata/re/444599890/b/lib.frame-base/source/module/fmodule.cpp:307
    line table: lib.frame-base/source/module/fmodule.cpp:186 (start line: 181)
4   ?
    additional inline call: Steinberg::FModuleBase::~FModuleBase()
          caller:     /Users/buildserver/Builddata/re/444599890/b/lib.frame-base/source/module/fmodule.cpp:593
    line table: lib.frame-base/source/module/fmodule.cpp:64 (start line: 63)
5   Steinberg::FModule::~FModule()
          defined in: ...890/b/lib.frame-base/source/module/fmodule.cpp:590

As said, this is just an example, There are other plug-ins that crash in the same way. Also EastWest’s Opus is crashing Dorico’s audio engine on quit.
I’d be happy to help and find out together what’s going on there.
Cheers,
Ulf

Hi @reuk , please excuse me, I know that bumping is not welcome, but I did not get any reaction so far. I forgot to mention that I am one of the Steinberg devs and it is odd that I can only tell our customers, that it is a refcount problem in Juce, so I’d like to help to fix the issue by any means.
Best regards, Ulf

The entire team has been busy this week with the Audio Developer Conference. I’ve requested a Dorico 5 NFR, and will investigate this issue next week.

Hi @reuk , thanks for your response. I will wait patiently

Having investigated this issue, I believe this to be a bug in Dorico.

Dorico calls IPluginFactory3::setHostContext() on the JUCE plugin factory. In the implementation of this function, we increment the refcount on the IHostApplication pointer, and store it.

When Dorico’s audio engine quits, it calls release on the JUCE plugin factory. The plugin factory is still holding a pointer to the IHostApplication, and calls release on this pointer. However, at this point, the IHostApplication has already been freed (incorrectly, because we still hold a reference to it), and the program crashes.

To fix this issue, Dorico must ensure that the IHostApplication object is still alive at the point where it attempts to release the IPluginFactory3. Another approach might be to call setHostContext again, passing nullptr, just before destroying the IHostApplication object.

I’ve created a topic to track this issue on Dorico’s side here:

Hi @reuk , to give feedback on this topic, actually you were right, it was a fault on the VSTAudioEngine side, but we have fixed it now.
And don’t wonder, no, it did not take that long to fix it, we just did not have it in focus because of other, more important work. Once looking deeper into the code and debugger, it became quickly clear what went wrong and how to fix.

1 Like