MessageManager assert being hit in Logic AU

While debugging an issue in Logic on an M1, I’ve been getting the odd crash when switching presets in the plugin. This seems to be hitting the JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN in Component::removeChildComponent.

It seems to be hitting this while removing a component. But there is no clue as to which component. My suspicion is that something else has gone wrong and the assert is being hit in the editor destructor.

I’m also getting crashes with release builds. Can anyone suggest a way to debug this further?

Screenshot and stack trace below.

juce::Component::removeChildComponent(int, bool, bool) juce_Component.cpp:1550
juce::Component::removeChildComponent(int) juce_Component.cpp:1543
juce::Component::deleteAllChildren() juce_Component.cpp:1607
JuceAU::EditorCompHolder::~EditorCompHolder() juce_AU_Wrapper.mm:1491
JuceAU::EditorCompHolder::~EditorCompHolder() juce_AU_Wrapper.mm:1490
JuceAU::EditorCompHolder::~EditorCompHolder() juce_AU_Wrapper.mm:1490
std::__1::default_delete<JuceAU::EditorCompHolder>::operator()(JuceAU::EditorCompHolder*) const memory:1428
std::__1::unique_ptr<JuceAU::EditorCompHolder, std::__1::default_delete<JuceAU::EditorCompHolder> >::reset(JuceAU::EditorCompHolder*) memory:1689
std::__1::unique_ptr<JuceAU::EditorCompHolder, std::__1::default_delete<JuceAU::EditorCompHolder> >::operator=(std::nullptr_t) memory:1647
JuceAU::JuceUIViewClass::deleteEditor(objc_object*) juce_AU_Wrapper.mm:1641
JuceAU::deleteActiveEditors() juce_AU_Wrapper.mm:1607
JuceAU::~JuceAU() juce_AU_Wrapper.mm:189
JuceAU::~JuceAU() juce_AU_Wrapper.mm:185
APFactory<AUMIDILookup, JuceAU>::Destruct(void*) ComponentBase.h:236
ComponentBase::AP_Close(void*) ComponentBase.cpp:121
AudioComponentInstanceDispose 0x0000000184cad4cc

It looks like the entire plugin instance is being destroyed, based on the stack trace you provided. How are you switching presets - are you using some option in Logic? If you’re using a button in your plugin editor, that’s a bit more unusual. I’d be very surprised if Logic were to destroy the plugin instance each time it reported a program change.

Are you able to reproduce the same behaviour in any of the JUCE example plugins after adding similar preset handling code?

Sorry I should clarify; it’s not really a “preset” in the sense of being connected to any of the preset/program related API’s, its more a change of internal data, which may result in some MIDI being altered - its a MIDI effect plugin. The switch is triggered by mouse clicks in the UI. The crash seems to happen at random after having played at least one note, and clicking a few times on different “presets”.

My guess is that it might be outputting MIDI messages that Logic doesn’t like. I’ve already done some fixes in this area, using the very helpful Scripter with a MIDI Monitor script.

Very strange. I’m happy to investigate further, but it sounds like it will be quite difficult to reproduce the crash in a demo project.

Is your version of JUCE reasonably up-to-date? I fixed an issue with AU MIDI handling on M1 machines in March 2021 where padding between consecutive MIDI messages was not being respected.

If the messages you’re sending are particularly unusual it’s possible you might be hitting a broken edge-case in the MIDI 1 to UMP MIDI conversion code. You could try logging all of the MIDI messages that are sent by your plugin before a crash, and then try playing these messages back from a very simple “MIDI playback” plugin to see whether specific messages are really causing the crash. If you can find a consistent message sequence that causes a crash, then I can try debugging the same sequence here and check whether the issue is somewhere in JUCE’s MIDI handling.

Thanks @reuk. I tested on 6.0.8 as well as the the latest tip of develop yesterday.

I’ll see if we can ascertain some more info on the issue and report back here.

Hey @reuk

We’ve deduced that the issue happens only on Logic on M1 Macs. Running under Rosetta apparently “fixes” the issue.

It seems to be do with sending lots of data on lots of channels at the same time.

Here is a test project: big-midi-buffer-plugin.zip (6.8 KB)

It looks like the issue might be to do with sending a big chunk of data in one go.

  • I arranged a channel strip so that your test plugin is first in the chain, and the JUCE MIDILogger example is second.
  • Then, I hit the button in your plugin’s editor.
  • Instead of seeing 256 pitchbend messages in the MIDILogger window, I see 86, followed by random garbage messages. The ‘random’ messages change each time I quit and restart Logic, so I’m guessing that something somewhere is reading past the end of a buffer.

I also tried adjusting the IPlugMIDIEffect project from the IPlug2 repo to see whether it behaved in a similar way to the JUCE plugin in Logic - unfortunately, I wasn’t able to load that plugin at all!

Finally, I tried loading your plugin and the MIDILogger in the AudioPluginHost, both as AudioUnits. There, I see the expected output in the MIDILogger window.

At the moment, this is looking like a Logic bug to me. I’d need to reproduce the issue in a minimal, completely JUCE-free plugin to make sure, though.

2 Likes

Thanks for testing it. Yes, from speaking to @t0m and from our testing, it does seem like it might be a Logic bug. We also don’t strictly need to be sending quite so much data, so I’m also working on a way to reduce that which might also sidestep this issue.

1 Like

I’ve put together a demo project that reproduces the problem without using JUCE at all. I’m now confident that the problem is in Logic 10.7.1 (arm native).

I’ll report this to Apple. Demo project is below, in case you want to try reproducing my results, reporting to Apple yourself, etc.

testau.zip (3.7 KB)

1 Like

I’ve contacted Apple and they’ve confirmed that they’re aware of the issue and are working on a solution.

3 Likes

Great, thanks for putting the AU test project together and reporting back.