Crash when setStateInformation

Hi, in my host I have a situation that is going me mad…

When I save state of a plugin loaded I call this code.

    MemoryBlock m;
    node->getProcessor()->getStateInformation (m);
    xmlElement->createNewChildElement (ayra::IDs::STATE)->addTextElement (m.toBase64Encoding());

While when I lad the state of that plugin:

    if (!node.get())                               { return; }
    if (!stateEntity.hasTagName(ayra::IDs::STATE)) { return; }
    
    AudioProcessor* processor = node->getProcessor();
    if (!processor)                                { return; }
    
    MemoryBlock m;
    m.fromBase64Encoding (stateEntity.getAllSubText());
    processor->setStateInformation (m.getData(), (int) m.getSize());

when the plugin is in AudioUnit format all works fine, while when it’s in VST3 format app crashes (while processor->setStateInformation (m.getData(), (int) m.getSize()); ) in line 546 of vector.h

    size_type size() const _NOEXCEPT
        {return static_cast<size_type>(this->__end_ - this->__begin_);}

with error JUCE Message Thread (1): EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

Any Idea of what’s happening? thank you!

Is this with any VST3 plugin? can you reproduce this with one of the JUCE demo plugins for example?

1 Like

Have a look at the backtrace and find the nearest point inside your code before the exception. You’re probably trying to use objects that haven’t been created yet.
Every host uses its own startup sequence, this explains why VST3 crashes and AU doesn’t… it may not crash in a different VST3 host.

1 Like

@anthony-nicholls & @ZioGuido

Both suggestions were useful, in AudioPluginHost it works and debugging I figure out that the problem is that parameters are not initialized.

In AudioPluginHost the restoring is done sync auto createInstanceWithFallback = & → std::unique_ptr , while I’m trying to do these stuffs async, getting resulting node added to graph in callback and from this the pluginInstance and the AudioProcessor, but it seems that node in callback ready but not yet the processor, so the question is:

There’s a way to know if the processor is fully initialized?

To explain better, with this code it doesn’t works (But I’d like to use this approach for some reasons):

     graph.createNewNode(PluginDescriptionAndPreference { pd },
                                          &position, undoManager, nodeUuid,
                                          [this, nodeXml] (AudioProcessorGraph::Node::Ptr node) {
           
    updateNodeLayoutFromXml(*nodeXml.getChildByName (ayra::IDs::LAYOUT), node);
    updateNodeStateFromXml (*nodeXml.getChildByName (ayra::IDs::STATE ), node);
    updateNodeFromXml      (graph, nodeXml, node);
    if (connect) { restoreConnectionsFromXml(graph, nodeXml); }
});

while with this it works:

String errorMessage;
if (auto instance = graph.pluginsManager.getAudioPluginFormatManager().createPluginInstance (pd.pluginDescription,graph.graph.getSampleRate(),graph.graph.getBlockSize(),errorMessage))
{
    if (auto node = graph.graph.addNode (std::move (instance)))
    {
        updateNodeLayoutFromXml(*nodeXml.getChildByName (ayra::IDs::LAYOUT), node);
        updateNodeStateFromXml (*nodeXml.getChildByName (ayra::IDs::STATE ), node);
        updateNodeFromXml      (graph, nodeXml, node);
        if (connect) { restoreConnectionsFromXml(graph, nodeXml); }
    }
}