Strange bug on Array::add() after migrating to 1.52

Hi,

I’m having a strange bug after migrating to version 1.52. I have tracked it down to juce_VST_Wrapper.cpp, at the line:

    activePlugins.add (this);

in the constructor. Surprisingly, the activePlugins array does not store the JuceVSTWrapper instance passed. Instead I think it creates an uninitialized entry. As a result, an assertion fails later on in the process.

What could possibly be wrong?

For information, I’m including here the add method from the 1.52 framework:

void add (ParameterType newElement)
	{
		const ScopedLockType lock (getLock());
		data.ensureAllocatedSize (numUsed + 1);
		new (data.elements + numUsed++) ElementType (newElement);
	}

Thanks for any help!

Mariano

This is making a copy of the object passed in. If you don’t have a copy constructor, then you better use OwnedArray instead.

Thanks, but that’s Juce framework code. I don’t think anything with that is wrong; it would have shown elsewhere, otherwise. But then there could be a wrong setting that’s preventing a proper copy to be created.

Nope, that code looks perfectly ok to me. It’s just an Array <void*>, so it’s just storing a pointer, nothing fancy. I think you’re probably misinterpreting some other kind of problem, e.g. a plugin being deleted twice for some reason.

What I don’t understand is that I go step by step in the add method, and I can see that the data member is allocated one entry after data.ensureAllocatedSize, but then that pointer is never replaced. Is that the correct behaviour?

I don’t know exactly what you’re seeing, but the C++ is definitely correct - it’d be a compiler error if it failed. But I use Array<void*> in lots of places, and if it didn’t work, it’d break a whole load of stuff.

I’m really lost here. I have just temporarily (will of course remove it afterwards) updated the Juce_VST_Wrapper.cpp by adding jassert (activePlugins.contains (this)) after the add:

And the assertion fails… I don’t understand how that can happen, specially in the same member.

I know it must be a configuration problem somewhere, but it would really help me if you could give me a direction, because I’m going crazy.

Make sure you don’t mix amalgamated files with some other source files (rebuild everything, clean all project, try not to use amalgamated headers / cpp files).

The main problem you might hit when you’re using the VST wrapper code is that the VST files also include the juce header files, so you must make sure that they are picking up the exact same version of juce headers that the rest of your app is using, or there’ll be all kinds of nasty linkage trouble.

I have really cleansed up any references to other Juce files in my code, but no luck. Currently I can see that what fails is in:

The end pointer gets set to the same value as e. It’s not incremented. As a result, we are never entering the loop. How can this happen? I’m not that familiar with pointer operations. Am I linking with a wrong library?

The pointers e and end are equal if numUsed is 0, so the problem isn’t in contains(). As said above, I don’t think the problem lies in the Array’s code. You call contains() directly after add() where numUsed is increased, so if the code would be executed as it should numUsed wouldn’t be 0 (unless it’s -1 before the add() which would hang apps calling contains() before they add anything)

Chris

When there are zero elements in the array, this is the right behaviour.
did you check extras\audio plugins\wrapper\juce_PluginHeaders.h for cross reference to juce_amalgamated.h?

Sorry, forgot to mention that I can see numUsed has the value of 1 in the debugger. That’s why it feels so wrong.

Seriously: there’s no bug in those Array methods. No question about that.

You need to think more laterally… E.g. is your destructor getting a re-entrant callback from something that happens during the shutdownJuce_GUI() function (i.e. after the plugin has been removed from the list but before its destructor has completed) ?

I have never doubted the Array class and its methods. Sorry if the title of my thread is misleading. I’m just trying to understand at which exact place the framework “derails” so as to have a hint of what could be the reason the assert is triggered. This pointer incrementation is puzzling, so I thought it could result from something like:

a) debugger info not reliable
b) memory not allocated and as such the pointer is not incremented
c) pointer size being different (though that would be something;-)

Anyway, I understand that it may be pointless to concentrate on that. I’ll probably recreate a new brand plugin through The Jucer and copy my existing code progressively into that. But I would have loved to find out what is wrong with my current project. It was working perfectly under Juce 1.51.

And to answer your question, I never reach any shutdownJuce_GUI method, as the assert fails before that.

Well, I’ve love to know what’s going on if you track it down, but yes, you’re definitely wasting your time looking for bugs in the array. Sounds to me like something’s got corrupted and the debugger is a bit confused.

Finally, after painful debugging, I managed to track down the problem to a combination of keeping a non-static pointer to AudioPluginFormatManager in my singleton manager class and having JUCE_CHECK_MEMORY_LEAKS (temporarily) disabled. After defining my pointer as static and reenabling the leaks check flag, it now seems to work fine (still touching wood;-).

I just need to solve a CallbackMessage leak problem now, but that should be a walk in the park compared to the problem faced before.

Thanks a lot for your help!

Mariano

CallbackMessages can sometimes leak when they’re still queued for delivery in the system message queue when the plugin has been unloaded. Nothing we can do about that, really, so if it’s only one or two objects, it’s probably not worth worrying about.