VST3 Access Violation

I'm sure it's something I'm doing wrong, but I'm struggling to work out where to start looking. I have a plugin I'm working on that works fine as a VST2, but when I load it as a VST3 in the Juce Plugin Host and then launch the GUI, I get the following error:

Unhandled exception at 0x54AE2458 (ScopeSyncVST-Debug.vst3) in PluginHost.exe: 0xC0000005: Access violation reading location 0xFEEEFEEE.

The line of code it breaks at is in juce_Component.cpp:


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();
        }
...
}

In case it's useful, here's the stack trace:

    ScopeSyncVST-Debug.vst3!juce::Component::setBounds(int x, int y, int w, int h) Line 1182    C++
    ScopeSyncVST-Debug.vst3!juce::Component::setBounds(const juce::Rectangle<int> & r) Line 1254    C++
    ScopeSyncVST-Debug.vst3!juce::JuceVST3EditController::JuceVST3Editor::ContentWrapperComponent::resized() Line 478   C++
    ScopeSyncVST-Debug.vst3!juce::Component::sendMovedResizedMessages(bool wasMoved, bool wasResized) Line 1209 C++
    ScopeSyncVST-Debug.vst3!juce::Component::setBounds(int x, int y, int w, int h) Line 1191    C++
    ScopeSyncVST-Debug.vst3!juce::Component::setSize(int w, int h) Line 1234    C++
    ScopeSyncVST-Debug.vst3!juce::JuceVST3EditController::JuceVST3Editor::ContentWrapperComponent::resizeHostWindow() Line 495  C++
    ScopeSyncVST-Debug.vst3!juce::JuceVST3EditController::JuceVST3Editor::attached(void * parent, const char * type) Line 365   C++
    PluginHost.exe!00dd16d7()   Unknown
    [Frames below may be incorrect and/or missing, no symbols loaded for PluginHost.exe]    
    PluginHost.exe!00dd52e7()   Unknown
    PluginHost.exe!0107df1a()   Unknown
    PluginHost.exe!010100d2()   Unknown
    PluginHost.exe!01120de2()   Unknown
    PluginHost.exe!0113544b()   Unknown
    PluginHost.exe!00e70734()   Unknown
    PluginHost.exe!0127ae39()   Unknown
    PluginHost.exe!010df483()   Unknown
    PluginHost.exe!0111ff63()   Unknown
    PluginHost.exe!011255e4()   Unknown
    PluginHost.exe!012c4f0b()   Unknown
    [External Code] 
    PluginHost.exe!012c4f0b()   Unknown
    [External Code] 
    PluginHost.exe!00f0f913()   Unknown
    PluginHost.exe!00f14917()   Unknown
    PluginHost.exe!00f14886()   Unknown
    [External Code] 
    PluginHost.exe!01201353()   Unknown
    PluginHost.exe!01237079()   Unknown
    PluginHost.exe!011fc93d()   Unknown
    [External Code]

I'm building for 32bit, but on 64bit Windows 7, using VSE2013.

Looks like a dangling pointer, but it's impossible for us to guess what you could be doing to cause it - that's something for you and your debugger to work out, I'm afraid.

Cool, thanks for replying so quickly. So, you think the fact that it works as VST2 and not as VST3 is just a red herring then?

Should the fact that it crashes at that particular line give me any clues in my hunt? I'm invariably using ScopedPointers and OwnedArrays in the code, but I guess there must be some circumstance under which I'm mis-managing my memory (happens as we get older!)

So, you think the fact that it works as VST2 and not as VST3 is just a red herring then?

Yup, it's very easy to get bugs that only show up when used in particular circumstances. Debugging it is the only way to know for sure.

Just for the sake of my own sanity, I just built the Juce audio plugin demo and ran that in the debugger and that also caused an access violation when opening the GUI the audio plugin host. It broke in almost the same spot (a line later in the juce_Component.cpp file). Loading the same plugin as VST2 worked fine.

I updated from github this afternoon, made sure I have the latest VST3 SDK from Steinberg and did a fresh (debug) build of the audio plugin host. I'll try on my Windows 8 install to see if I get the same outcome there.

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.