JUCE 7, VST2 and pluginval testing crashes

Hello JUCEers.

I am having a lot of problems with VST2 when updating to JUCE 7 and using pluginval. Maybe this is the wrong forum for this, please forgive me if that is the case.

When running pluginval after a few opening and closings I get an exception, which I don’t get for the VST3 tests. I’ve searched on the forums and can’t find any helpful information regarding this.

Tried emptying the PluginEditor of everything but setting the size and fill with a background colour in paint but it still happens.

Any ideas?

|>|pluginval.exe!juce::WeakReference<juce::Component,juce::ReferenceCountedObject>::SharedPointer::get() Line 129|C++|
|---|---|---|
| |pluginval.exe!juce::WeakReference<juce::Component,juce::ReferenceCountedObject>::Master::getSharedPointer(juce::Component * object) Line 170|C++|
| |pluginval.exe!juce::WeakReference<juce::Component,juce::ReferenceCountedObject>::getRef(juce::Component * o) Line 204|C++|
| |pluginval.exe!juce::WeakReference<juce::Component,juce::ReferenceCountedObject>::WeakReference<juce::Component,juce::ReferenceCountedObject>(juce::Component * object) Line 84|C++|
| |pluginval.exe!juce::Component::SafePointer<juce::VSTPluginWindow>::SafePointer<juce::VSTPluginWindow>(juce::VSTPluginWindow * component) Line 2293|C++|
| |pluginval.exe!juce::VSTPluginWindow::vstHookWndProc(HWND__ * hW, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 3305|C++|
| |[External Code]||
| |MyPlugin.dll!juce::HWNDComponentPeer::destroyWindowCallback(void * handle) Line 2701|C++|
| |MyPlugin.dll!juce::HWNDComponentPeer::callFunctionIfNotLocked(void *(*)(void *) callback, void * userData) Line 3952|C++|
| |MyPlugin.dll!juce::HWNDComponentPeer::~HWNDComponentPeer() Line 1753|C++|
| |[External Code]||
| |MyPlugin.dll!juce::Component::removeFromDesktop() Line 772|C++|
| |MyPlugin.dll!juce::Component::~Component() Line 529|C++|
| |MyPlugin.dll!JuceVSTWrapper::EditorCompWrapper::~EditorCompWrapper() Line 989|C++|
| |[External Code]||
| |MyPlugin.dll!JuceVSTWrapper::deleteEditor(bool canDeleteLaterIfModal) Line 882|C++|
| |MyPlugin.dll!JuceVSTWrapper::handleCloseEditor(JuceVSTWrapper::VstOpCodeArguments __formal) Line 1657|C++|
| |MyPlugin.dll!JuceVSTWrapper::dispatcher(int opCode, JuceVSTWrapper::VstOpCodeArguments args) Line 908|C++|
| |MyPlugin.dll!JuceVSTWrapper::dispatcherCB(Vst2::AEffect * vstInterface, int opCode, int index, __int64 value, void * ptr, float opt) Line 955|C++|
| |pluginval.exe!juce::VSTPluginInstance::dispatch(int opcode, int index, __int64 value, void * const ptr, float opt) Line 1744|C++|
| |pluginval.exe!juce::VSTPluginWindow::dispatch(const int opcode, const int index, const int value, void * const ptr, float opt) Line 3265|C++|
| |pluginval.exe!juce::VSTPluginWindow::closePluginWindow() Line 3244|C++|
| |pluginval.exe!juce::VSTPluginWindow::~VSTPluginWindow() Line 2814|C++|
| |[External Code]||
| |pluginval.exe!deleteEditorOnMessageThread::__l2::<lambda>() Line 188|C++|
| |[External Code]||
| |pluginval.exe!`juce::MessageManager::callAsync'::`2'::AsyncCallInvoker::messageCallback() Line 197|C++|
| |pluginval.exe!juce::InternalMessageQueue::dispatchMessage(juce::MessageManager::MessageBase * message) Line 202|C++|
| |pluginval.exe!juce::InternalMessageQueue::dispatchMessages() Line 240|C++|
| |pluginval.exe!juce::InternalMessageQueue::dispatchNextMessage(bool returnIfNoPendingMessages) Line 125|C++|
| |pluginval.exe!juce::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 266|C++|
| |pluginval.exe!juce::MessageManager::runDispatchLoop() Line 109|C++|
| |pluginval.exe!juce::JUCEApplicationBase::main() Line 269|C++|
| |pluginval.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 173|C++|
| |[External Code]||

Have you tested any of the JUCE example plugins to see whether those also have the same problem? If they do, then the problem is likely to be in the JUCE wrapper or hosting code.

Sorry for a slow reply, I’ve been investigating thoroughly.
It also happens using the AudioPluginDemo.dll, and to trigger it on that plugin I have to click on my code editor so that the plugin is not on top when running pluginval.

In juce_VSTPluginFormat.cpp, When I changed

void broughtToFront() override
{
    activeVSTWindows.removeFirstMatchingValue (this);
    activeVSTWindows.add (this);

   #if JUCE_MAC
    dispatch (Vst2::effEditTop, 0, 0, nullptr, 0);
   #endif
}

to

void broughtToFront() override
{
    // activeVSTWindows.removeFirstMatchingValue (this);
    // activeVSTWindows.add (this);

   #if JUCE_MAC
    dispatch (Vst2::effEditTop, 0, 0, nullptr, 0);
   #endif
}

It passes (change is only for pluginval). :thinking: Seems to be to be some kind of race on the contents of activeVSTWindows which is just a static variable.

1 Like

Thanks for the additional details. I’ve reproduced and debugged the problem, and we should have a fix out in a few days. Pluginval will also need to be updated once the fix has been merged.

2 Likes

ping @dave96 you might be interested in this as well. :pray:

Is this something that could affect other hosts, or is it just going to be isolated to pluginval?

It looks like it might affect other VST2 hosts too.

That’s interesting, something due to a recent change or do we expect to affect things going back a long time?

Difficult to say; the fix changes lines in the VSTPluginWindow that were last touched ten years ago. The particular behaviour we’re seeing, where broughtToFront is called while the editor destructor is running, might have been in place all along, or it might have been introduced recently.

1 Like

I saw this commit pushed to develop:

Does this mean this is fixed? :smiley:

If so, could you outline what changes are needed on the host side?

Thanks! :slight_smile: :pray:

…Is maybe an update of pluginval to point to this commit in juce sufficient? :slight_smile:

You’re right, the issue should be fixed by this commit:

Just updating the version of JUCE used in pluginval should be sufficient to avoid the issue.

Great! Thanks! :smiley:

If someone wants to do that on a fork then open a PR it would happen much quicker :wink:
That way I can check it all still builds on the CI.

I opened a PR, but am running into another issue with the JUCE VST3 demos segfaulting on all platforms after updating pluginval to latest develop.

@reuk I couldn’t reproduce locally on my own plugins, but after building the JUCE demos and running them through pluginval, I saw EXC_BAD_ACCESS in getVst3SpeakerArrangement, specifically on BigInteger::isNegative() inside the std::find_if — maybe related to this recent commit?

On the pluginval side, it’s coming from the supportedLayoutsWithNamedChannels call inside listBuses(false): pluginval/BusTests.cpp at 8756d8426529305f1efa5c653fb4688b2edd3d2a · Tracktion/pluginval · GitHub — happy to make any changes there if you see something that’s off!

I can repro this now, investigating…

1 Like

Looks like a typo here:

I think that should be getBus (isInput, i) rather than getBus (true, i).

Thanks for reporting! Pluginval catching real bugs once again…

2 Likes

Great work! I feel bad, I just lopped this into your lap instead of digging into the actual logic and helping out more. Thanks for looking into it!

The fix is finally public:

No worries, I shouldn’t be committing bugs in the first place!

1 Like

Awesome, this makes pluginval green again, thanx!

very high bar of you, let me know if you find the secret!