NSException on closing a window in kiosk mode, created during handleAsyncUpdate()


#1

Hi JUCE Team,

It seems we’ve found an NSException crash in a very specific case of windowing code.

  1. creating a window inside a handleAsyncUpdate(), which happens e.g. in a comboBoxChanged().
  2. Manually set the window to kiosk mode, by clicking the green + button
  3. Close the window programmatically (in our case by clicking on the content component), calling the window destructor.

The above sequence of events results in an NSException, and an EXC_BAD_ACCESS on [NSApp run]. Running the zombie profiler shows us a selector is sent to an already released object, and the call stack shows it probably has something to do with the kiosk animation. Creating a window outside of the AsyncUpdater works fine.

We’ve created a sample project which exhibits the described bug. The crash doesn’t happen every time (which only makes it worse).

Stijn Frishert
Moditone


crashlog.txt (7.6 KB)
Main.h (2.6 KB)
Main.cpp (213 Bytes)
MainComponent.h (1.1 KB)
MainComponent.cpp (1.2 KB)


#2

Hi JUCE Team,

I was wondering if anyone could react to the above bug report. Or are we doing something wrong by trying to create a window during an async update (it’s the main thread, right)? This bug is one of the last remaining hurdles before we can put our software in beta release.

Stijn


#3

Yes, you’re right - there’s nothing special about handleAsyncUpdate. Can you get the bug to trigger in other situations?


#4

Well, it’s hard to trigger in the first place. I just opened a window, put it in kiosk and closed it again for about 30 times before it started happening again. As with all multithreading bugs, most annoying are the ones that don’t always trigger. But I do have some new data: using MessageManager::callAsync() gives the same problem.

We suspect it has something to do with macOS running an animation when shutting down a window in kiosk mode. Apparently it tries to send an objc message to an object that doesn’t exist anymore.

image

A screenshot of where the app crashes with JUCE_CATCH_UNHANDLED_EXCEPTIONS on:


#5

Yes, I think you’re right.

I’ve had a go a reproducing the problem and it’s a much more reproducible crash if you either move the mouse extremely quickly after clicking or do a speedy double click. The fix will probably be to wait until kiosk mode exit has finished animating in a destructor somewhere or unsubscribe to events - but I can’t see anything obvious.


#6

Whew, I’m happy you were able to reproduce it!

Yes, it sounds as if some process needs to wait for the animation to finish before wrapping up. Any idea when someone could thoroughly look at it? Should we file a bug report over on GitHub?


#7

If you could confirm that this fixes your crashes I’ll cherry pick the commit to the master branch.


#8

Ooh! I’ll give it a go and report back, thanks! :slight_smile:


#9

Nope, I’m afraid it’s still happening! :confused:

Found out I could save the Zombie Profiler state, I’ve uploaded it here in case it could help. Crash happens in trace 5.

Also, enabling Zombie Objects in diagnostics prints this in the console: JUCEView_581ab408a55fe2e1 _layoutEngine]: message sent to deallocated instance 0x60000032e240. Trying to provide as much information as possible.


#10

Are you still getting a crash with the sample project you sent? I’ve tried 50 times or so under different conditions and can’t get it to fall over.


#11

Sorry for the delay, I wanted to triple check and make sure what’s happening.
Good news is I can’t seem to trigger the crash anymore! I’ve tried 50 times in the sample project, as well as in our own actual app. Not sure what happened with that last crash, but for now it seems to be working. Thanks, Tom! :smiley:

(If the crash does occur again I’ll let you know.)