VST3 Access Violation

I've tested on my Windows 8.1 32bit install (same PC) and getting the same outcome with the Juce audio plugin demo. Also tested on a separate laptop running Windows 8.1 64bit and the same.

I'm using VSE2013 in all cases and launch the Juce audio plugin host as the Debugging Command. I built the plugin host in Debug configuration.

I've also tested my plugin using Steinberg's VST3 test host and the GUI loads up without a problem. One thing I haven't tested is launching the Steinberg VST3 test host as the Debugging Command in VSE2013. Let me know if you think that's worth me trying too.

It's very puzzling - I don't see that crash myself, and looking at the stack trace you posted, there's really no reason it should be failing there. It almost looks like some kind of link error or other build problem. If you could post another stack trace with the latest code from github, that might be helpful.

Hi Jules,

The exception I get from the Juce Demo Plugin running inside the Juce Plugin Host is:

Unhandled exception at 0x7453CB49 in PluginHost.exe: 0xC0000005: Access violation reading location 0x00000000.

The stack trace is:

     00000000()    Unknown
     [Frames below may be incorrect and/or missing]    
>    JuceDemoPlugin.vst3!juce::Component::setBounds(int x, int y, int w, int h) Line 1185    C++
     JuceDemoPlugin.vst3!juce::Component::setBounds(const juce::Rectangle<int> & r) Line 1254    C++
     JuceDemoPlugin.vst3!juce::JuceVST3EditController::JuceVST3Editor::ContentWrapperComponent::resized() Line 478    C++
     JuceDemoPlugin.vst3!juce::Component::sendMovedResizedMessages(bool wasMoved, bool wasResized) Line 1209    C++
     JuceDemoPlugin.vst3!juce::Component::setBounds(int x, int y, int w, int h) Line 1191    C++
     JuceDemoPlugin.vst3!juce::Component::setSize(int w, int h) Line 1234    C++
     JuceDemoPlugin.vst3!juce::JuceVST3EditController::JuceVST3Editor::ContentWrapperComponent::resizeHostWindow() Line 495    C++
     JuceDemoPlugin.vst3!juce::JuceVST3EditController::JuceVST3Editor::attached(void * parent, const char * type) Line 365    C++
     PluginHost.exe!juce::VST3Classes::VST3PluginWindow::attachPluginWindow() Line 1624    C++
     PluginHost.exe!juce::VST3Classes::VST3PluginWindow::componentVisibilityChanged() Line 1546    C++
     PluginHost.exe!juce::ComponentMovementWatcher::componentVisibilityChanged(juce::Component & __formal) Line 122    C++
     PluginHost.exe!juce::ListenerList<juce::ComponentListener,juce::Array<juce::ComponentListener *,juce::DummyCriticalSection,0> >::callChecked<juce::Component::BailOutChecker,juce::Component &>(const juce::Component::BailOutChecker & bailOutChecker, void (juce::Component &) * callbackFunction, juce::Component & param1) Line 178    C++
     PluginHost.exe!juce::Component::sendVisibilityChangeMessage() Line 607    C++
     PluginHost.exe!juce::Component::setVisible(bool shouldBeVisible) Line 586    C++
     PluginHost.exe!PluginWindow::PluginWindow(juce::Component * pluginEditor, juce::AudioProcessorGraph::Node * o, PluginWindow::WindowFormatType t) Line 51    C++
     PluginHost.exe!PluginWindow::getWindowFor(juce::AudioProcessorGraph::Node * node, PluginWindow::WindowFormatType type) Line 187    C++
     PluginHost.exe!FilterComponent::mouseUp(const juce::MouseEvent & e) Line 405    C++
     PluginHost.exe!juce::Component::internalMouseUp(juce::MouseInputSource source, juce::Point<float> relativePos, juce::Time time, const juce::ModifierKeys oldModifiers) Line 2537    C++
     PluginHost.exe!juce::MouseInputSourceInternal::sendMouseUp(juce::Component & comp, juce::Point<float> screenPos, juce::Time time, const juce::ModifierKeys oldMods) Line 148    C++
     PluginHost.exe!juce::MouseInputSourceInternal::setButtons(juce::Point<float> screenPos, juce::Time time, const juce::ModifierKeys newButtonState) Line 191    C++
     PluginHost.exe!juce::MouseInputSourceInternal::handleEvent(juce::ComponentPeer & newPeer, juce::Point<float> positionWithinPeer, juce::Time time, const juce::ModifierKeys newMods) Line 306    C++
     PluginHost.exe!juce::MouseInputSource::handleEvent(juce::ComponentPeer & peer, juce::Point<float> pos, __int64 time, juce::ModifierKeys mods) Line 567    C++
     PluginHost.exe!juce::ComponentPeer::handleMouseEvent(int touchIndex, juce::Point<float> pos, juce::ModifierKeys newMods, __int64 time) Line 91    C++
     PluginHost.exe!juce::HWNDComponentPeer::doMouseEvent(juce::Point<float> position) Line 1655    C++
     PluginHost.exe!juce::HWNDComponentPeer::doMouseUp(juce::Point<float> position, const unsigned int wParam) Line 1766    C++
     PluginHost.exe!juce::HWNDComponentPeer::peerWindowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 2407    C++
     PluginHost.exe!juce::HWNDComponentPeer::windowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 2331    C++
     [External Code]    
     PluginHost.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 135    C++
     PluginHost.exe!juce::MessageManager::runDispatchLoopUntil(int millisecondsToRunFor) Line 99    C++
     PluginHost.exe!juce::MessageManager::runDispatchLoop() Line 87    C++
     PluginHost.exe!juce::JUCEApplicationBase::main() Line 239    C++
     PluginHost.exe!WinMain(void * __formal, void * __formal, const char * __formal, int __formal) Line 102    C++
     [External Code]    

And the code it stops at is:

void Component::setBounds (const int x, const int y, int w, int h)
{
    ...
        if (showing)
        {
            if (wasResized)
                repaint();
            else if (! flags.hasHeavyweightPeerFlag)
                repaintParent();
        }
        else if (cachedImage != nullptr)
        {
            cachedImage->invalidateAll();
        }
>>>        if (flags.hasHeavyweightPeerFlag)
            if (ComponentPeer* const peer = getPeer())
                peer->updateBounds();
        sendMovedResizedMessages (wasMoved, wasResized);
    }
}

So, there are some differences in what I see when I run my own plugin, but quite close in location.

P.S. For reference, I get a slightly different exception again on my laptop, but with the same stack trace and stopping at the same line of code.

Unhandled exception at 0x90900000 in PluginHost.exe: 0xC0000005: Access violation executing location 0x90900000.

It makes no sense.. It looks like the pluginEditor object (or the ContentWrapperComponent object that owns it) is getting deleted in resizeHostWindow() somewhere between line 486, which works, and line 489, where it seems to be junk. I've no idea how that could happen! Could you step through it in the debugger and get any clues about what's going on in there?

I set a debug breakpoint at line 486 of juce_VST3_Wrapper.cpp and the line is hit 3 times after attempting to load the GUI and before the access violation. It seems like I get different exceptions depending on whether I step through or just "Continue" between points. In the case where I hit Continue twice and then start stepping through, I generally see the pluginEditor's owner becoming a nullptr. Other times I've seen it become 0xfeeefeee

Here's some screengrabs showing the second time the breakpoint is hit and the third:

and

Let me know if there's any other information you'd like me to try to grab beyond the screenshots and notes above.

Thanks,
Will

Bizarre.. Could be some other thread deleting the editor? Have you tried putting a breakpoint in the destructor of AudioProcessorEditor to see what's deleting it?

Here's the stack trace for the entry to the destructor of JuceDemoPluginAudioProcessorEditor

>   JuceDemoPlugin.vst3!JuceDemoPluginAudioProcessorEditor::~JuceDemoPluginAudioProcessorEditor() Line 61   C++

    [External Code] 
    JuceDemoPlugin.vst3!juce::ContainerDeletePolicy<juce::AudioProcessorEditor>::destroy(juce::AudioProcessorEditor * object) Line 48   C++
    JuceDemoPlugin.vst3!juce::ScopedPointer<juce::AudioProcessorEditor>::~ScopedPointer<juce::AudioProcessorEditor>() Line 100  C++
    JuceDemoPlugin.vst3!juce::JuceVST3EditController::JuceVST3Editor::ContentWrapperComponent::~ContentWrapperComponent() Line 463  C++
    [External Code] 
    JuceDemoPlugin.vst3!juce::ContainerDeletePolicy<juce::JuceVST3EditController::JuceVST3Editor::ContentWrapperComponent>::destroy(juce::JuceVST3EditController::JuceVST3Editor::ContentWrapperComponent * object) Line 48 C++
    JuceDemoPlugin.vst3!juce::ScopedPointer<juce::JuceVST3EditController::JuceVST3Editor::ContentWrapperComponent>::~ScopedPointer<juce::JuceVST3EditController::JuceVST3Editor::ContentWrapperComponent>() Line 100    C++
    [External Code] 
    JuceDemoPlugin.vst3!Steinberg::FObject::release() Line 72   C++
    JuceDemoPlugin.vst3!Steinberg::CPluginView::release() Line 92   C++
    PluginHost.exe!juce::ComSmartPtr<Steinberg::IPlugView>::~ComSmartPtr<Steinberg::IPlugView>() Line 143   C++
    PluginHost.exe!juce::VST3Classes::VST3PluginInstance::hasEditor() Line 1937 C++
    PluginHost.exe!juce::AudioProcessor::createEditorIfNeeded() Line 235    C++
    PluginHost.exe!PluginWindow::getWindowFor(juce::AudioProcessorGraph::Node * node, PluginWindow::WindowFormatType type) Line 168 C++
    PluginHost.exe!FilterComponent::mouseUp(const juce::MouseEvent & e) Line 405    C++
    PluginHost.exe!juce::Component::internalMouseUp(juce::MouseInputSource source, juce::Point<float> relativePos, juce::Time time, const juce::ModifierKeys oldModifiers) Line 2537    C++
    PluginHost.exe!juce::MouseInputSourceInternal::sendMouseUp(juce::Component & comp, juce::Point<float> screenPos, juce::Time time, const juce::ModifierKeys oldMods) Line 148    C++
    PluginHost.exe!juce::MouseInputSourceInternal::setButtons(juce::Point<float> screenPos, juce::Time time, const juce::ModifierKeys newButtonState) Line 191  C++
    PluginHost.exe!juce::MouseInputSourceInternal::handleEvent(juce::ComponentPeer & newPeer, juce::Point<float> positionWithinPeer, juce::Time time, const juce::ModifierKeys newMods) Line 306    C++
    PluginHost.exe!juce::MouseInputSource::handleEvent(juce::ComponentPeer & peer, juce::Point<float> pos, __int64 time, juce::ModifierKeys mods) Line 567  C++
    PluginHost.exe!juce::ComponentPeer::handleMouseEvent(int touchIndex, juce::Point<float> pos, juce::ModifierKeys newMods, __int64 time) Line 91  C++
    PluginHost.exe!juce::HWNDComponentPeer::doMouseEvent(juce::Point<float> position) Line 1655 C++
    PluginHost.exe!juce::HWNDComponentPeer::doMouseUp(juce::Point<float> position, const unsigned int wParam) Line 1766 C++
    PluginHost.exe!juce::HWNDComponentPeer::peerWindowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 2407    C++
    PluginHost.exe!juce::HWNDComponentPeer::windowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 2331    C++
    [External Code] 
    [Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]    
    PluginHost.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 135  C++
    PluginHost.exe!juce::MessageManager::runDispatchLoopUntil(int millisecondsToRunFor) Line 99 C++
    PluginHost.exe!juce::MessageManager::runDispatchLoop() Line 87  C++
    PluginHost.exe!juce::JUCEApplicationBase::main() Line 239   C++
    PluginHost.exe!WinMain(void * __formal, void * __formal, const char * __formal, int __formal) Line 102  C++
    [External Code] 

Hmm. That might be the first time an editor is deleted, but it's not the relevant one - we need to find the call that happens during the bit of code that we were talking about above.

Unfortunately I'm going to be away from my computer for the next week, but I'll check again when I get back. However, IIRC, that breakpoint was only hit once before the crash.

I don't know if this helps, but please see below a screen capture of a debug run through showing the single entry to that destructor. Please let me know if I'm doing anything daft when trying to identify the issue here.

 

If anyone has time, it would be great if they could see if they have the same problem. It's very quick to test and it would be great if I could find a way to move forward with this.

It's on my to-do-list!

Mysteriously, after some directory restructuring and a reinstall of Visual Studio, I have been successful in loading a VST3 version of my plugin in the Juce audio plugin host. If I manage to get to the bottom of exactly why it's now working when it wasn't before, I'll post back here, but in the meantime apologies for any time wasted.

Hmm. I said earlier in this thread that it seemed like a link error. You were probably mis-linking different versions of a library or some kind of class.

1. Run demo host.

2. Load an instance of Vienna Ensemble VST3

3. Exit host or delete the filter

4, Crash at component->terminate(); in destructor

    ~VST3PluginInstance()
    {
        jassert (getActiveEditor() == nullptr); // You must delete any editors before deleting the plugin instance!
        releaseResources();
        if (editControllerConnection != nullptr && componentConnection != nullptr)
        {
            editControllerConnection->disconnect (componentConnection);
            componentConnection->disconnect (editControllerConnection);
        }
        editController->setComponentHandler (nullptr);
        if (isControllerInitialised)    editController->terminate();
        if (isComponentInitialised)     component->terminate(); //Crash here
        componentConnection = nullptr;

If you bypass this you get a AttributeList Leak.

Any ideas?

BTW this does not happen with 64 bit version of Vienna Ensemble and I noticed that when the Vienna VST3 instance is loaded the edtor dissappears and then reappears.

 

In situations like this when a plugin crashes inside its own code, and when other plugins don't crash in the same situation, then you should be telling the plugin authors about it rather than us.

Usually this kind of thing happens when the host is behaving in a way which is perfectly valid, but where a particular plugin isn't robustly written. E.g. there may be a few different orders in which the host could legitimately choose to call shutdown functions, but the plugin has only been tested in hosts which happen to do it in a particular way. Sometimes it's possible for us to make changes to our hosting code to work around problems like this, but it's impossible to know what to change without feedback from the plugin authors themselves.

Ok I'll contact Vienna but you know they are going to say it's Juce. You may be right that all the hosts have written around glitch. or that the hosts delete the plugin in a different order than juce.

I am and I pretty sure it's the order of objects being released. I tried changing the order of them but it still crashes what ever I do.

For now I don't release it and of course when the applicaion exists their is an Attribute List still hanging around.

They may say it's juce's fault, and that could be true. Our hosting code could indeed be doing something silly, and all other plugins may just be lucky not to have a problem with it.

But my point is we can't debug someone else's plugin to see what's crashing it.

If they run it in a debugger and see our host doing something wrong or dangerous, then we'd be happy to fix that. But it's just not possible for us to magically discover why someone else's closed-source plugin is crashing!