VST3 Scanning Error

I have seen a number of topics related to this, but none which seem to properly resolve the issue.

When scanning for VST3s I pick up a load of exceptions. Firstly I get multiple originating from here:

These seem to be handled so that the app can continue. However once scanning is seemingly completed, another more vague exception is thrown in the runDispatchLoop() function.

This causes a full crash and provides a pretty useless call stack:
Screenshot 2021-11-02 at 08.53.17

One thing which might shed some light on this is the exception name which is this:
libc++abi: terminating with uncaught exception of type boost::exception_detail::clone_impl<boost::exception_detail::error_info_injectorboost::lock_error >: boost: mutex lock failed in pthread_mutex_lock: Invalid argument

I have tried recreating this in the AudioPluginHost bundled with JUCE however, the same errors do not occur. If anyone could help me find out what this is or debug it further it’d be greatly appreciated.

This is likely to be caused by a specific plugin. Please can you tell us which plugin is failing to scan correctly?

I believe it was failing when scanning the 4 Izotope RX7 plug-ins however after removing them from the folder, the same scanning problem seems to occur.

This error does not happen in the AudioPluginHost, if it was a specific plug-in causing this would that be the case?

On initial reading I got the impression that some plugins were scanning correctly, but maybe I misunderstood. Are any plugins scanning successfully, or does the very first plugin scanned cause a failure? From the crash you’re getting, it looks like a specific plugin is crashing (boost exceptions aren’t used anywhere in JUCE, so unless your host uses boost then the crash probably originates in a plugin).

I think it maybe a specific plugin. After removing some quite heavy plugins (Izotope, etc.) it seems to scan ok. What I don’t understand is why the AudioPluginHost seems to be able to deal with those yet our application crashes?

Are you using the latest version of the AudioPluginHost? If so, does it work with both in-process and out-of-process scanning? In order to rescan plugins, you’ll need to remove them from the list before initiating the scan.

Ah this is interesting. I’ve just seen that the AudioPluginHost is catching the ones which are crashing in my app.

How are these crashes being caught? I am using the same scanner as the one in the plugin host (I think).

It turns out it’s only marking those as failed to initialise after first crashing the app when trying to scan them. This causes an uncaught exception:

libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘nextEventMatchingMask should only be called from the Main Thread!’
terminating with uncaught exception of type NSException

and also marks a crash in the destructor of ‘VSTComSmartPtr’

Just to answer your question, yes we are using AudioPluginHost from JUCE 6.1.2. I am not sure what you mean by in process and out-of-process scanning?

Thanks, I’ll try getting demo copies of Ozone 9 Elements and RX7 Voice De-noise and see whether I can reproduce the issue.

The very newest PluginHost contains an out-of-process scanning feature that can be enabled here:

Screenshot 2021-11-02 at 10.53.28

Some plugins encounter problems when they are instantiated on a background thread, which is the technique used by the in-process plugin scanner. Scanning out-of-process solves this problem by allowing the scan to happen on the scanner process’ main thread. It also has the benefit that if a plugin does crash for some reason, the crash won’t take down the main host app.

Just moved onto the develop branch and can confirm that scanning out-of-process succeeded while scanning in-process failed

In that case, I think it’s likely that these plugins simply cannot be scanned on a background thread. That said, I just tried downloading the newest versions of these plugins and they scanned successfully in-process, so perhaps the newer versions are more robust.

To make the plugin scanning in your project more resilient, there are a couple of things you could try:

  • Disable background thread scanning (ensure allowPluginsWhichRequireAsynchronousInstantiation is disabled when creating the PluginListComponent). This will block the main thread during the scan, which may lead to a poor user experience. If any plugins crash during the scan, your host will also crash.
  • Alternatively, implement your own out-of-process scanner. This is a bit trickier, but it provides a better user experience. You can check the source code of the AudioPluginHost to see how the subprocess scanner is implemented there.

Great! Thanks for the help and the recommendations. I will take a look at the AudioPluginHost and get some inspiration from there.

Not saying this is why it failed, but know that some plugins crash on purpose when running in debug mode.
The rules when building a plugins scanner are:

  • Scan in release mode
  • Scan in a child process
  • Scan on the message thread
    Missing any of these rules will get you in trouble eventually.

Yeah seems like the child process is the way to go. That seems to be how the AudioPluginHost works using the JUCE ChildProcessCoordinator class. Haven’t noticed any difference between debug and release modes, but perhaps that is down to the specific plugins I am scanning.

Yes it really depends on the plugin. Some will show an alert saying “The plugin cannot run in debug mode” before crashing. Some will crash right away. Some will run fine.
Another rule I forgot to mention:

  • Scan plugins one by one (1 child process per plugin)

When you Scan lots of plugins in the same process, they sometime corrupt each others memory. You could still decide to scan many plugins in 1 process, but when the process crashes you should resume at the plugin that crashed, because it may have crashed because of previous scans.
Good luck!