Crash while running NSAlert.runModal

My application overrides AppDelegate.menuWillOpen(). During startup of the application (in AppDelegate.applicationDidFinishLaunching) I attempt to install a privileged helper tool using SMAppService. On detecting that the tool needs to be allowed/installed I open the Login Items & Extensions settings and then display a modal dialog, advising the user to authorise the privileged helper. Then the application crashes with a message in the crash file

Application Specific Information: BUG IN CLIENT OF LIBDISPATCH: trying to lock recursively

Maybe I could avoid this by removing the menuWillOpen() override so am looking for a workaround. i.e. is it possible to install the override function programmatically later during initialisation, rather then declaring it in an extension.

I have attached the crash log.

Answered by DTS Engineer in 886547022

I suspect you’re deadlocking against your self. Consider the crashing thread backtrace:

0   libdispatch.dylib … _dispatch_once_wait.cold.1 + 196
1   libdispatch.dylib … _dispatch_once_wait + 60
2   ChronyControl     … AppDelegate.menuWillOpen(_:) + 488
…
43  ChronyControl     … one-time initialization function for shared + 36
44  libdispatch.dylib … _dispatch_client_callout + 16
45  libdispatch.dylib … _dispatch_once_callout + 32
46  ChronyControl     … AppDelegate.applicationDidFinishLaunching(_:) + 472

Frame 46 is called dispatch_once for something called shared (as indicated by frame 43). That runs through a bunch of logic and eventually gets to frame 2, which is calling dispatch_once again. I suspect it’s doing it for the same shared value, and hence the crash. And both frame 46 and frame 2 are your code.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

To help clarify the above, the menuWillOpen() function is declared as an AppDelegate:NSMenuDelegate extension.

extension AppDelegate: NSMenuDelegate {
	func menuWillOpen(_ menu: NSMenu)
	{
		if menu == myMenu {
			// enable/disable menu items
		}
	}
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var myMenu: NSMenu!
// NSApplicationDelegate functions
}

Where and how do you call NSAlert?

I suspect you’re deadlocking against your self. Consider the crashing thread backtrace:

0   libdispatch.dylib … _dispatch_once_wait.cold.1 + 196
1   libdispatch.dylib … _dispatch_once_wait + 60
2   ChronyControl     … AppDelegate.menuWillOpen(_:) + 488
…
43  ChronyControl     … one-time initialization function for shared + 36
44  libdispatch.dylib … _dispatch_client_callout + 16
45  libdispatch.dylib … _dispatch_once_callout + 32
46  ChronyControl     … AppDelegate.applicationDidFinishLaunching(_:) + 472

Frame 46 is called dispatch_once for something called shared (as indicated by frame 43). That runs through a bunch of logic and eventually gets to frame 2, which is calling dispatch_once again. I suspect it’s doing it for the same shared value, and hence the crash. And both frame 46 and frame 2 are your code.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks Quinn

I have worked around this by removing the NSMenu.delegate assignment from the .xib and called myMenu.delegate = self after return from the NSAlert.runModal() call.

Crash while running NSAlert.runModal
 
 
Q