After updating JUCE, pluginval started crashing during our Audio Unit validation. Pluginval ends with “pluginval received Segmentation fault: 11, exiting immediately”.
Have you tried attaching a debugger? Might also be worth adding address/thread sanitizer. Have you also tried with any of the audio plugin demos? Do they have the same problem?
At what level? I just had this exact thing, and “fixed” it. So if it’s at level 3 that it bugs out I might be able to help you.
To debug, I had to make very sure that I’m launching the pluginval version that I just (Debug target!) compiled with Xcode. Then, compile my plugin from Xcode as well, then attach to pluginval process, make sure pluginval points to your just compiled build, make sure pluginval Options→Validate in-process is turned on, then run the test. If I forgot one of these steps I would always land in some assembler code.
Alright, after a debugging session, I traced the crash back to a call to updateHostDisplay() inside prepareToPlay() in our plugin.
Maybe calling updateHostDisplay() from prepareToPlay() is not safe, although this used to work for us and passed pluginval. I wonder if that JUCE commit, moving files without UI dependencies to juce_audio_processors_headless, somehow changed the behaviour of updateHostDisplay.
The crash easy to reproduce:
Create a new audio plug-in using Projucer (JUCE 8.0.12)
Call updateHostDisplay() from prepareToPlay()
Run pluginval (develop branch) with the plugin .component path as command line argument and see it crash at the end after SUCCESS logs.
My system is macOS 15.6.1 (24G90).
The crash itself is not very clear, see the screenshot below.
Do you get a more detailed stack trace if you click the “show all frames” button (funnel icon) at the top of the call stack window? If so, that might provide some more hints.
I think this might be awkward to track down if it crashes in system code - sometimes these kinds of crashes are caused by incorrect reference counting of Objective-C types, so perhaps you could try running the app under the Instruments “allocations” checker to see whether that gives you any new information.
As @anthony-nicholls mentioned earlier, it’s also a good idea to enable address sanitizer for your plugin build and the pluginval build. It’s possible that there’s a memory issue in pluginval or in the plugin, but the symptomatic crash happens some time after the memory issue first occurs.
I’ve digged a bit deeper into updateHostDisplay and figured out that it fails ONLY for the parameter info changed flag. I previously just relied on the default flags by calling updateHostDisplay().
I’ve tried all 4, see below:
updateHostDisplay(ChangeDetails().withParameterInfoChanged(true)); // Crash
updateHostDisplay(ChangeDetails().withProgramChanged(true)); // OK
updateHostDisplay(ChangeDetails().withNonParameterStateChanged(true)); // OK
updateHostDisplay(ChangeDetails().withLatencyChanged(true)); // OK
Luckily, for my plugin I just need the withNonParameterStateChanged to be set, and I can confirm it passes pluginval now, so I don’t need to further investigate this for myself.
I have seen something similar before, might related. I would guess the problem is that pluginval does not call prepareToPlay on the message thread for AU. Here is a log from quite a while ago (an old JUCE 8 version, and I disable sanitizers for AU since then).
Perhaps yes for AU compiled by JUCE? Given sampleRate, latency and some other variables are not atomic in juce::AudioProcessor, perhaps pluginval should call prepareToPlay on the message thread or acquire a message thread lock.
I would see yes but it is up to the JUCE team. In my own JUCE fork I just change those parameters, especially the latencySamples, to std::atomic to simplify the problem Otherwise the thread sanitizer will randomly throw errors if I call setLatencySamples later on the message thread.