AU plugin crash when quitting host during playback, VST3 quits fine


I need a hand troubleshooting a very odd bug I’ve encountered when building/testing my plugins. So far I have built two plugins and now I’m in the stage of optimising/refining. Here is what I’ve found.

Plugin 1:
Builds to AU, builds to VST3. (Debug and Release)
(Tested in Release mode, but same happens Debug) When I quit Ableton Live and the plugin is on a channel while playing, using the AU version, I get a EXC_BAD_ACCESS (SIGSEGV) error and Ableton gives me crash report.
This does not happen with the VST3 version. i.e. VST3 version works fine, does not crash when I quit Ableton during playback.

Plugin 2:
Builds to AU but only in Debug mode. If I try to build to AU in release mode, I see the .component file but Ableton does not register it.
Builds to VST3 fine in Debug and Release.
Like Plugin 1, when I quit Ableton during playback using AU version, I get EXC_BAD_ACCESS (SIGSEGV) and a crash report. VST3 quits fine in debug and release.

Here is a screengrab of the crash report:

Is there someone familiar with AU/VST3 architecture that could tell me what I’ve been doing wrong? Am I missing a validation step? Could I be missing some code in the destructors of my clasees? I am very perplexed.

Any help would be amazing.

Am I missing a validation step?

From my personal experience, both debug & release AU can be detected by Reaper.

Could I be missing some code in the destructors of my classes?

I would like to say that it is the most likely reason. I suggest testing your plugin with a validator, for example pluginval.

Looks like it’s crashing in a function of a class named wvWavesV13_0_0_129::PluginViewManager. Do you have any Waves plugins running in the session? If so, does the crash still happen if you remove the Waves plugins?

Yes, in a project with no other plugins and just one channel, I get the seg fault.
Still very confused however why my second plugin does not show up in ableton when built in release mode. I will have a look into pluginval to see if somethings going wrong.

Update: I have been messing around in pluginvaland have found the following. I have just freshly compiled “Plugin 2” to release, using the same code, to VST3 and to AU. When I validate the VST3, it says All tests passed, but when I try it on the AU it does not pass the first validation step:

....///End of the VST3 test
Starting test: pluginval / Fuzz parameters...

Time taken to run test: 0

Time taken to run all tests: 12 secs
All tests completed successfully

Finished validating: /Users/dario/Library/Audio/Plug-Ins/VST3/PullUpMachine.vst3
pluginval v0.2.7 - JUCE v5.4.7
Started validating: /Users/dario/Library/Audio/Plug-Ins/Components/PullUpMachine.component
Random seed: 0x57a6979
Validation started: 9 Sep 2023 6:09:12pm

Strictness level: 5
Starting test: pluginval / Scan for known types: /Users/dario/Library/Audio/Plug-Ins/Components/PullUpMachine.component...
Num types found: 0
!!! Test 1 failed: No types found
FAILED!!  1 test failed, out of a total of 1

Finished validating: /Users/dario/Library/Audio/Plug-Ins/Components/PullUpMachine.component

This is not the same problem that is causing my plugins to crash but it is still very odd. Do
I have to set some specific flag for AU plugins such as Manufacture ID etc (I thought I had already done that).

Plugin 1 passes all tests on pluginval (VST3 and AU) on a strictness of 10, but still causes the Seg Fault in Ableton. I am pretty perplexed

Looking at older posts, specifically this one, it seems they are talking about using smart pointers for objects. So far I have just been using normal objects to hold all my audio processors and gui elements. So for my Attached Slider solution it looks like this:

struct AttachedSlider
    using Slider = juce::Slider;
    using Attachment = juce::SliderParameterAttachment;
    AttachedSlider(juce::AudioParameterFloat* parameter) :
        attachment(*parameter, slider)
        slider.setTextBoxStyle(juce::Slider::TextBoxBelow, false, 50, 16);

    Slider slider;
    Attachment attachment;

And in my PluginProcessor.h:

    Clipper clipper;
    juce::dsp::Oversampling<float> oversampling;

Should I be using unique_ptrs instead? and why?

Do I have to set some specific flag for AU plugins such as Manufacture ID etc. (I thought I had already done that).

The only thing I can think of is AU_MAIN_TYPE ***. Also, make sure not to use the same PLUGIN_MANUFACTURER_CODE and PLUGIN_CODE for different plugins (at least one of them should be different? not very sure about this).

Plugin 1 passes all tests on pluginval (VST3 and AU) on a strictness of 10, but still causes the Seg Fault in Ableton. I am pretty perplexed

I understand your feelings. However, I am not able to help you in this situation. From my personal experience, plugins that pass the pluginval on strictness 10 are very robust. You may use the JUCE default editor to see whether the DSP part is OK.

Should I be using unique_ptrs instead? and why?

If normal objects are already enough, I won’t consider smart pointers as necessary. However, I’m not a C++ expert :smiling_face_with_tear:

Update: I have been further testing with pluginval, as well as some other things. Very strange findings. The crash only occurs when the Editor is open. i.e if I quit Ableton and the editor is closed it quits fine, no seg fault. So I thought it could be a problem with my Editor and all my gui components.
So i replaced the line in PluginProcessor.h in “createEditor()” to a generic editor to see if it was the fault of my gui code.

juce::AudioProcessorEditor* SimpleClipAudioProcessor::createEditor()
    return new SimpleClipAudioProcessorEditor (*this);
    //return new juce::GenericAudioProcessorEditor (*this); - old

Crash still happens…
The only thing i can think is that it is something to do with the communication between Editor and Processor, which happens via the Parameters. I have handled the parameters using an APVTS as well as a vector of Ranged Audio Parameter pointers, mainly following the guidance from this video.

    apvts(*this, nullptr, "Parameters", param::createParamterLayout()),
    for (int i = 0; i < param::NumParams; i++)
        auto pID = static_cast<param::PID>(i);
        apvts.addParameterListener(param::toID(pID), this);
    inputGain = dynamic_cast<juce::AudioParameterFloat*>(params[static_cast<int>(param::PID::InputGain)]);
    outputGain = dynamic_cast<juce::AudioParameterFloat*>(params[static_cast<int>(param::PID::OutputGain)]);

Gets more and more perplexing the more I look at this.
What other profilers/debugging platforms can I use to diagnose these sorts of issues?