Restoring AU state crashes on Logic Pro 10.6.1 on M1

Restoring AU state crashes on Logic Pro 10.6.1 on M1. I have created a minimal program to reproduce here: juce_bugs/AUCrash at master · FigBug/juce_bugs · GitHub

It’s pretty simple, it creates a 2 KB MemoryBlock:

void AUCrashAudioProcessor::getStateInformation (juce::MemoryBlock& destData)
{
	destData.setSize (2200);
	destData.fillWith (0);
}

Then in restore state it is really slow checking the data is still all zeros

void AUCrashAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
	criticalSection.enter();
	
	juce::Thread::sleep (1000);
	
	uint8_t* p = (uint8_t*)data;
	for (int i = 0; i < sizeInBytes; i++)
		if (p[i] != 0)
			ohShit = true;

	criticalSection.exit();
}

If you open a Project with a bunch of instances of the plugin, Logic will crash.

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib               	0x000000019fda2178 objc_msgSend + 24
1   com.apple.CoreFoundation      	0x000000019ff9c670 CFDictionaryGetValueIfPresent + 64
2   com.Me.AUCrash                	0x000000010b9de448 JuceAU::RestoreState(void const*) + 220 (juce_AU_Wrapper.mm:740)
3   com.Me.AUCrash                	0x000000010ba01210 AUBase::DispatchSetProperty(unsigned int, unsigned int, unsigned int, void const*, unsigned int) + 2456 (AUBase.cpp:914)
4   com.Me.AUCrash                	0x000000010b9d8080 AUMethodSetProperty(void*, unsigned int, unsigned int, unsigned int, void const*, unsigned int) + 124 (AUPlugInDispatch.cpp:167)
5   com.apple.audio.AudioToolboxCore	0x00000001a144b8c8 std::__1::__function::__func<setStateAndNotify(__CFDictionary const*, AUAudioUnitV2Bridge*, unsigned int)::$_7, std::__1::allocator<setStateAndNotify(__CFDictionary const*, AUAudioUnitV2Bridge*, unsigned int)::$_7>, void ()>::operator()() + 60
6   com.apple.audio.AudioToolboxCore	0x00000001a144b718 void applesauce::dispatch::v1::async<dispatch_to_main_queue_with_timeout(std::__1::function<void ()>)::$_4>(NSObject<OS_dispatch_queue>*, dispatch_to_main_queue_with_timeout(std::__1::function<void ()>)::$_4&&)::'lambda'(void*)::__invoke(void*) + 112
7   libdispatch.dylib             	0x000000019fd5c420 _dispatch_client_callout + 20
8   libdispatch.dylib             	0x000000019fd69e1c _dispatch_main_queue_callback_4CF + 836
9   com.apple.CoreFoundation      	0x00000001a00439ec __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16

I have worked around the crash by using CFRetain/CFRelease on the data block passed intoJuceAU::RestoreState. However I think this just makes the race condition a lot less likely, and is not actually a fix. reFX: retain preset data while loading preset · reFX/JUCE@51ce1fc · GitHub

I’m pretty sure this is actually a bug in the new AUHostingService that isn’t retaining the memory block passed in correctly, since I can’t see anything in the JUCE code that is draining the NSAutoreleasePool.

The Logic project to reproduce is in the repo. I have not been able to reproduce this on an Intel mac.

Does anybody know the best way to report bugs to Apple?

5 Likes

Thank you for your investigation!

To report bugs to Apple go to
https://developer.apple.com/bug-reporting/
which leads you to
https://feedbackassistant.apple.com/


This issue (or a very similar one) appears to also happen under macOS 11.1 on x86 Macs, not only M1 Macs. I received crash reports by a Final Cut Pro (v10.4.10) user, who encounters a crash of one of my plug-ins approximately every 30 minutes. It occurs when restoring the AU state.

Some of the crash reports show that a plug-in by another developer is crashing as well. This developer also uses JUCE. I obviously can’t fully symbolicate those reports, but the stack traces look similar to the stack traces in the crash reports for my plug-in.

The crashes come in two flavours,
either triggered by line 725 JuceAU::RestoreState(void const*) (juce_AU_Wrapper.mm:725) [1]
or by line 741 JuceAU::RestoreState(void const*) (juce_AU_Wrapper.mm:741) [2].

A stack trace for [1]:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib               	    0x00007fff20218d29 objc_msgSend + 41
1   com.klangfreund.lufsmeter2    	    0x0000000109f4bde1 JuceAU::RestoreState(void const*) (juce_AU_Wrapper.mm:725)
2   com.klangfreund.lufsmeter2    	    0x0000000109f521c4 AUMethodSetProperty(void*, unsigned int, unsigned int, unsigned int, void const*, unsigned int) (AUPlugInDispatch.cpp:167)
3   com.apple.audio.AudioToolboxCore	0x00007fff218aacda std::__1::__function::__func<setStateAndNotify(__CFDictionary const*, AUAudioUnitV2Bridge*, unsigned int)::$_7, std::__1::allocator<setStateAndNotify(__CFDictionary const*, AUAudioUnitV2Bridge*, unsigned int)::$_7>, void ()>::operator()() + 46
4   com.apple.audio.AudioToolboxCore	0x00007fff218aa9a1 void applesauce::dispatch::v1::async<dispatch_to_main_queue_with_timeout(std::__1::function<void ()>)::$_4>(NSObject<OS_dispatch_queue>*, dispatch_to_main_queue_with_timeout(std::__1::function<void ()>)::$_4&&)::'lambda'(void*)::__invoke(void*) + 71
...

A stack trace for [2]:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib               	    0x00007fff20218d1d objc_msgSend + 29
1   com.apple.CoreFoundation      	    0x00007fff20410844 CFDictionaryGetValueIfPresent + 138
2   com.klangfreund.lufsmeter2    	    0x00000001087d9e51 JuceAU::RestoreState(void const*) (juce_AU_Wrapper.mm:741)
3   com.klangfreund.lufsmeter2    	    0x00000001087e01c4 AUMethodSetProperty(void*, unsigned int, unsigned int, unsigned int, void const*, unsigned int) (AUPlugInDispatch.cpp:167)
4   com.apple.audio.AudioToolboxCore	0x00007fff218aacda std::__1::__function::__func<setStateAndNotify(__CFDictionary const*, AUAudioUnitV2Bridge*, unsigned int)::$_7, std::__1::allocator<setStateAndNotify(__CFDictionary const*, AUAudioUnitV2Bridge*, unsigned int)::$_7>, void ()>::operator()() + 46
5   com.apple.audio.AudioToolboxCore	0x00007fff218aa9a1 void applesauce::dispatch::v1::async<dispatch_to_main_queue_with_timeout(std::__1::function<void ()>)::$_4>(NSObject<OS_dispatch_queue>*, dispatch_to_main_queue_with_timeout(std::__1::function<void ()>)::$_4&&)::'lambda'(void*)::__invoke(void*) + 71
...

I tried to witness such a crash under macOS 11.1 with my plug-in as well as with the
AUCrash plug-in by @RolandMR under Final Cut Pro 10.5 with the debugger attached. No crash occurred for two hours.

I have submitted the issue via Feedback Assistant, haven’t heard anything back.

Have you tried contacting Markus who reached out to plugin developers about the Apple ProAudio Seed program?

Perhaps he will know some way to expedite this seeing as it’s something they should be very interested in solving.

I’ve also had this problem reported by an M1 Mac user… HTH! Pete

Similar issue here :frowning:

Edit: i have contacted Markus about this.
Edit2: its on their TODO list now.

That crash is fixed in macOS 11.3

3 Likes

Great to hear. Thanks a lot :slight_smile:

Sorry to revive this old topic.

Is there any potential advert side effect in having these CFRetain /CFRelease lines in the AU wrapper code?
This seems to solve a crashing issue for one of my users running Logic 10.5.0 on Catalina.

@RolandMR do you see any potential side effect in using your workaround?
Even if the problem appears to be solved with current MacOS versions, some users with an older OS are still in a situation where this fix does improve there experience…

We are still using this fix in a plugin that is widely distributed. I has reduced crashes, no negative issues seen. I don’t see a reason not to apply the patch, just be aware it doesn’t fix the crash 100% of the time, just makes it a lot less likely.

2 Likes

Thanks, that is good to hear!
Don’t you think this should make it into the official JUCE codebase?