Can't use multiple VSTs at once in the Plugin Host

#1

Might be a long shot, but here goes…

I’m using the plug-in host, built in the usual way (through Xcode on OSX). I’m generating VSTs using the JUCE code, but built with a different build system (I mention this in the off-chance that I missed a flag or something). I can load any of my VSTs into the plugin host when there is only a single VST in the search path folders. It works. When I add a second VST, I reliably get a crash (EXC_BAD_ACCESS) with the stack trace below when calling dispatch(plugInOpcodeGetProgramName, …). This is repeatable with different first and second plugins. My AudioProcessor::getProgramName() returns String() for all of my plugins, like it does in the demo plugin.

Any thoughts?

#2  0x00000001086986f7 in JuceVSTWrapper::dispatcherCB(VstEffectInterface*, int, int, long long, void*, float) ()
#3  0x00000001000da2b5 in juce::VSTPluginInstance::dispatch(int, int, long long, void*, float) const at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Builds/MacOSX/../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1234
#4  0x00000001000f01fd in juce::VSTPluginInstance::updateStoredProgramNames() at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Builds/MacOSX/../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1869
#5  0x00000001000efd7a in juce::VSTPluginInstance::initialise(double, int) at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Builds/MacOSX/../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:780
#6  0x00000001000da93c in juce::VSTPluginInstance::initialiseEffect(double, int) at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Builds/MacOSX/../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:734
#7  0x00000001000cc550 in juce::VSTPluginFormat::createPluginInstance(juce::PluginDescription const&, double, int, void*, void (*)(void*, juce::AudioPluginInstance*, juce::String const&)) at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Builds/MacOSX/../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:2868
#8  0x00000001000bedec in juce::AudioPluginFormat::createPluginInstanceOnMessageThread(juce::PluginDescription const&, double, int, juce::AudioPluginFormat::InstantiationCompletionCallback*) at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Builds/MacOSX/../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp:207
#9  0x00000001000bec37 in juce::AudioPluginFormat::createPluginInstanceAsync(juce::PluginDescription const&, double, int, juce::AudioPluginFormat::InstantiationCompletionCallback*) at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Builds/MacOSX/../../../../modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp:138
#10 0x00000001000bf500 in juce::AudioPluginFormatManager::createPluginInstanceAsync(juce::PluginDescription const&, double, int, juce::AudioPluginFormat::InstantiationCompletionCallback*) at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Builds/MacOSX/../../../../modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp:135
#11 0x000000010000211e in FilterGraph::addFilter(juce::PluginDescription const*, double, double) at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Source/FilterGraph.cpp:99
#12 0x000000010000ed3d in GraphEditorPanel::createNewPlugin(juce::PluginDescription const*, int, int) at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Source/GraphEditorPanel.cpp:869
#13 0x000000010000ec68 in GraphEditorPanel::mouseDown(juce::MouseEvent const&) at /Users/chetgnegy/NeptuneStudios/Neptune/Source/ThirdParty/Juce/JUCE/examples/audio plugin host/Source/GraphEditorPanel.cpp:862
0 Likes

#2

What are you attempting to access when you hit this? What are the states of all the variables? The stack trace on its own is not enough to narrow down the problem very much.

0 Likes

#3

Yes, sorry. And thank you, Tom. You and your team have always been very helpful with my questions in the past.

std::cout << opcode << " "<< index << " " << value << " " << ptr << " " << opt << std::endl;
result = vstEffect->dispatchFunction (vstEffect, opcode, index, value, ptr, opt);

Here are the list of args to dispatchFunction prior to the crash. This is 100% reproducible for me. Note that if I open StreamPlugin and Constellation in the reverse order, it is always the second one that breaks on the same line. I can successfully open multiple instances of the first plugin at once, it’s once I open the first different plugin.

You’ll also notice I’m trying to build the old VST format at v4.3.1. First off… I’m sorry, I know devs hate when someone brings them old code and complains. I’m picking this project up again after 2 years and I need to finish the job of getting my build system working for the state of the world then before I upgrade. (This whole adventure has been in trying to build JUCE with Bazel). So FWIW, I think this is not a bug in the JUCE library code. I never had these issues when building the plugins as JUCE recommends. (I’m sure you’re shaking your head at me now, haha) Any insights are appreciated.

JUCE v4.3.1
Attempting to load VST: /Users/chetgnegy/vst/StreamPlugin.vst
JUCE v4.3.1
Creating VST instance: StreamPlugin
Creating VST instance: StreamPlugin
49 0 0 0x0 0
Initialising VST: StreamPlugin (V1.0.0)
22 0 0 0x0 0
10 0 0 0x0 44100
11 0 512 0x0 0
0 0 0 0x0 0
2 0 0 0x0 0
31 1 1 0x0 0
31 0 1 0x0 0
32 1 1 0x0 0
32 0 1 0x0 0
35 0 0 0x0 0
29 0 -1 0x7fff5fbfe450 0
51 0 0 0x1006163b9 0
42 0 140734799796080 0x7fff5fbfd3e8 0
51 0 0 0x1006163b9 0
10 0 0 0x0 44100
11 0 512 0x0 0
12 0 1 0x0 0
71 0 0 0x0 0
51 0 0 0x100616387 0
51 0 0 0x100616387 0
51 0 0 0x100616387 0
48 0 0 0x7fff5fbfd7e0 0
48 0 0 0x7fff5fbfd7e0 0
51 0 0 0x100616387 0
Attempting to load VST: /Users/chetgnegy/vst/Constellation.vst
JUCE v4.3.1
Creating VST instance: Constellation
Creating VST instance: Constellation
49 0 0 0x0 0
Initialising VST: Constellation (V1.0.0)
22 0 0 0x0 0
10 0 0 0x0 44100
11 0 512 0x0 0
0 0 0 0x0 0
2 0 0 0x0 0
31 1 1 0x0 0
31 0 1 0x0 0
32 1 1 0x0 0
32 0 1 0x0 0
35 0 0 0x0 0
29 0 -1 0x7fff5fbfe450 0

I at first thought the -1 was a bad sign, but that seems to be ok based on the previous calls (the first plugin always handles it fine).

0 Likes

#4

More info:
EXC_BAD_ACCESS (code=2 address, 0x10b097010)

The bad access looks to be within the vstEffect itself, though not at a specific pointer mentioned in the members.

And here’s a dump of the state of vstEffect:

Printing description of this->vstEffect:
(juce::Vst2::VstEffectInterface *) vstEffect = 0x00000001020a5858
Printing description of this->vstEffect->dispatchFunction:
(pointer_sized_int (*)(juce::Vst2::VstEffectInterface *, int32, int32, pointer_sized_int, void *, float)) dispatchFunction = 0x0000000108903650 (StreamPlugin`JuceVSTWrapper::dispatcherCB(VstEffectInterface*, int, int, long long, void*, float))
Printing description of this->vstEffect->processAudioFunction:
<nil>
Printing description of this->vstEffect->setParameterValueFunction:
(void (*)(juce::Vst2::VstEffectInterface *, int32, float)) setParameterValueFunction = 0x0000000108903700 (StreamPlugin`JuceVSTWrapper::setParameterCB(VstEffectInterface*, int, float))
Printing description of this->vstEffect->getParameterValueFunction:
(float (*)(juce::Vst2::VstEffectInterface *, int32)) getParameterValueFunction = 0x0000000108903710 (StreamPlugin`JuceVSTWrapper::getParameterCB(VstEffectInterface*, int))
Printing description of this->vstEffect->numPrograms:
(juce::int32) numPrograms = 1
Printing description of this->vstEffect->numParameters:
(juce::int32) numParameters = 0
Printing description of this->vstEffect->numInputChannels:
(juce::int32) numInputChannels = 2
Printing description of this->vstEffect->numOutputChannels:
(juce::int32) numOutputChannels = 2
Printing description of this->vstEffect->flags:
(juce::int32) flags = 49
Printing description of this->vstEffect->hostSpace1:
<nil>
Printing description of this->vstEffect->hostSpace2:
(juce::pointer_sized_int) hostSpace2 = 4329202688
Printing description of this->vstEffect->latency:
(juce::int32) latency = 0
Printing description of this->vstEffect->deprecated1:
(juce::int32) deprecated1 = 0
Printing description of this->vstEffect->deprecated2:
(juce::int32) deprecated2 = 0
Printing description of this->vstEffect->deprecated3:
(float) deprecated3 = 0
Printing description of this->vstEffect->effectPointer:
(void *) effectPointer = 0x00000001020a5800
Printing description of this->vstEffect->userPointer:
<nil>
Printing description of this->vstEffect->plugInIdentifier:
(juce::int32) plugInIdentifier = 1349285223
Printing description of this->vstEffect->plugInVersion:
(juce::int32) plugInVersion = 100
Printing description of this->vstEffect->processAudioInplaceFunction:
(void (*)(juce::Vst2::VstEffectInterface *, float **, float **, int32)) processAudioInplaceFunction = 0x0000000108903720 (StreamPlugin`JuceVSTWrapper::processReplacingCB(VstEffectInterface*, float**, float**, int))
Printing description of this->vstEffect->processDoubleAudioInplaceFunction:
(void (*)(juce::Vst2::VstEffectInterface *, double **, double **, int32)) processDoubleAudioInplaceFunction = 0x0000000108903780 (StreamPlugin`JuceVSTWrapper::processDoubleReplacingCB(VstEffectInterface*, double**, double**, int))
Printing description of this->vstEffect->emptySpace:
(char [56]) emptySpace = ""
0 Likes

#5

EDIT: It seems to be coming from an address near vstEffect, I don’t think I can actually conclude that it is within the bounds of that object from the information given.

0 Likes

#6

Nothing is jumping out at me. The arguments to the callback look OK too.

0 Likes

#7

It’s possible that it’s some kind of confusion/collision when you have two dynamic libraries loaded into memory. If a build problem isn’t too unlikely then I’d suggest looking at the linking arguments and symbol visibility.

0 Likes

#8

OK, I will. Thank you. You mention symbol visibility (keeping in mind that my main experience in learning about linkers is this very issue), but I would expect that if there was a visibility issue that loading the plugin at all would be problematic.

Any specific symbols to look at beyond debugFunction?

0 Likes

#9

https://labjack.com/news/simple-cpp-symbol-visibility-demo

0 Likes

#10

I haven’t solved this yet, but I did want to thank you for the useful link. I’m learning a lot and I suspect your hunches are good that this is related to the problem.

0 Likes

#11

Yes, this was the missing flag. Thanks a lot, Tom.
-fvisibility-inlines-hidden

0 Likes