We are seeing a crash in Logic Pro X if the user removes our auwrapper-wrapped plugins any time that the user has clicked in the open plug-in window anywhere, and has not at some point closed the plug-in window prior to removing the plugin.
We are still on VST version 3.6.6, with VSTGUI v4.3. We’re trying to get a product out right away, but this bug is a major sticking point. Because of our tight schedule, we can’t update to the latest SDKs until the next maintenance release (unless we absolutely have to, which will push the release date back quite a while!).
Anyone seen this behavior, and know how to resolve it? (Our older versions, build with VST 3.6.5 and VSTGUI 4.2 under Mac OS 10.10 do not show this behavior, by the way.)
The latest SDK is what I was referring to, I was quoting the section between #if defined(MAC_OS_X_VERSION_10_11) and #else…so I meant neither have CFBundleUnloadExecutable() nor CFRelease() (unless your VST3 bundle retains itself).
Commenting out that code does indeed stop the crashing!
I’m a little worried about possible side-effects, such as static data, a thread singleton that runs at startup of the VST3 plug-in, and copy protection of the VST3 portion. Is this safe to do in all cases? Could it lead to problems with the items I’ve mentioned?
I’m also curious about your comment about “unless your VST3 bundle retains itself”. Should it? If so, how, exactly?
Sorry for all the questions. I really need to make sure I get this fix right before sending it out into the field.
I wish I still had the link to a technical note by Apple that stated that refraining from unloading the bundle executable in CFBundles that rely on the ObjC runtime is the way to go pretty clearly. Maybe bx_joscha can help out here as we had a similar issue during the development of the PA WPAPI Shell while I was still working at BX and I kept the link in a comment in the source code somewhere.
Side-effects: Well, it basically leads to an unbalanced retain count so it doesn’t behave differently as if an additional instance was still running when you close the last instance of your plugin. Another side-effect is that the library doesn’t have to be re-loaded and remapped once the first instance is/was open, so new instances should open up faster even if all instances were shut down already. Probably that doesn’t count much in the days of SSD and multiple GHz.
If you’re worried about dumping attacks: You could easily trash/restore sensitive data in your singleton during your implementation of DeinitModule() / InitModule()…but someone could still use a e.g. VM to watch the memory regardless of the problem under consideration.
On whether your bundle should retain itself: That would be one possible workaround to defeat the auwrapper’s final CFRelease(). In case of the CFUnloadBundleExecutable() call there is no remedy so there is no way around patching the auwrapper if you’re working with newer base SDKs.
It looks like all that is needed to prevent the crash is to remove that #if clause, allowing it to call only CFRelease, in all cases, rather than removing both calls.
Any reason that solution might cause a problem? It appears that that is what was the original code, and why someone added the “fix” for OS version 10.11, which instead seems to have broken things. I am using the latest SDK, which would be 10.12 (according to both Xcode target settings and a search of the SDKs inside Xcode).
(By the way, the singleton, which spawns a thread that I was worried about not getting shut down, does indeed still get shut down when the last instance of the plug-in is removed, despite the bundle not being released. It depends on the last effect class instance being destroyed, not the bundle being released, so that (and the copy protection) are fine.)