!!! BUG: The current event queue and the main event queue are not the same. Events will not be handled correctly. This is probably because _TSGetMainThread was called for the first time off the main thread.

Running my app from Xcode today I got this scary log:


!!! BUG: The current event queue and the main event queue are not the same. Events will not be handled correctly. This is probably because _TSGetMainThread was called for the first time off the main thread.


App got stuck, its window never appeared. Not sure what to make of it. Ran the app like 3-4 times and still got the same log. This app has been around for awhile never seen this before. Now all of a sudden, this no longer is logging out and the app is working like normal again with no code changes?

Answered by Frameworks Engineer in 301320022

This can happen if you spin up a worker thread from your main() or somewhere else that's very early in app launch, and the worker thread winds up calling into the event system prior to when the main thread calls -[NSApplication run]. Essentially, the thread that makes the first call to the event system winds up marking that thread as the main thread.


You might try debugging by setting a breakpoint on _TSGetMainThread (which is in CarbonCore.framework, but you don't need source to set a breakpoint; just add a symbolic breakpoint) and then launching your app. If your breakpoint is hit and the backtrace is for a thread that doesn't start with NSApplicationMain, then you have found your culprit.

IOS or MacOS ?


Did you have any OS update in between ?

This is a macOS app. I'm running 10.13.3 and Xcode 9.2 (9C40b).


I'm having a hard time getting it to happen again now. Not sure if this is just a Xcode bug or there is some race condition going on. I just have a boilerplate main.m, wasn't able to find a place in my code that gets the main thread before applicatonDidFinishLaunching:

I'd expect Cocoa to set up the event queue on the main thread right at app launch and block until that's done if the result is this kind of destruction.

Just happened again. When it happens the app just blocks.


Pausing in the debugger call stack for main thread is simply:


12 NSApplicationMain

11 -[NSApplication run];

10 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] ()

9 _DPSNextEvent ()

8 _BlockUntilNextEventMatchingListInModeWithFilter ()

7 ReceiveNextEventCommon ()

6 RunCurrentEventLoopInMode ()

5 CFRunLoopRunSpecific ()

4 __CFRunLoopRun ()

3 __CFRunLoopServiceMachPort ()

2 mach_msg ()

1 mach_msg_trap ()

And there is another Thread.

Thread 2:


3 OS_xpc_bool ()

2 start_wqthread ()

1 _pthread_wqthread ()

0 __workq_kernreturn ()

Accepted Answer

This can happen if you spin up a worker thread from your main() or somewhere else that's very early in app launch, and the worker thread winds up calling into the event system prior to when the main thread calls -[NSApplication run]. Essentially, the thread that makes the first call to the event system winds up marking that thread as the main thread.


You might try debugging by setting a breakpoint on _TSGetMainThread (which is in CarbonCore.framework, but you don't need source to set a breakpoint; just add a symbolic breakpoint) and then launching your app. If your breakpoint is hit and the backtrace is for a thread that doesn't start with NSApplicationMain, then you have found your culprit.

I don't know the answer, but you could try setting a symbolic breakpoint at "_TSGetMainThread", if that's an actual external symbol.


The message may or may not be genuinely about app startup, but if it is, there are a couple of pain points that would be worth investigating:


— Are you doing anything in the "applicationWillFinishLaunching" delegate method? There are some UI-related things that it's not good to attempt this early (e.g. displaying alerts, IIRC).


— Do you have any overrides to class "initialize" methods (Obj-C)? Because these run when the class is first referenced, and because one can chain to another, it's possible for custom code to run much earlier than you intended. It's also important to ensure that a given "initialize" method doesn't run twice.

I initiialy thought of setting a symbolic breakpoint but it was never hit. I put:


_TSGetMainThread and CarbonCore as the module (also tried with just Carbon, and with module blank).


I do have a class that runs a QOS_CLASS_BACKGROUND queue in its +load method to clean up some old cached files from time to time. None of the code I call within that background queue is main thread or asks for the main thread. Maybe some API underneath is calling it that I don't see.

>— Do you have any overrides to class "initialize" methods (Obj-C)?


No, but I do implement +load and spin off a queue with GCD with QOS_CLASS_BACKGROUND and clean up some old cached files, though I never ask for the main thread nor do I dispatch_async to the main thread.

That's odd, I just tried this with a very simple test app, set a breakpoint on _TSGetMainThread (no module), and got this backtrace at launch:


#0 0x00007fff40e3e127 in _TSGetMainThread ()

#1 0x00007fff40e3e0ba in GetThreadGlobals ()

#2 0x00007fff3d16c679 in -[NSApplication init] ()

#3 0x00007fff3d16c410 in +[NSApplication sharedApplication] ()

#4 0x00007fff3d16da1b in NSApplicationMain ()


That's what I'd expect to see.

Also tried setting it in a new project too but still not hitting the breakpoint.

I just hit the Breakpoint Navigator, hit the little + button at the bottom and choose "Symbolic Breakpoint..." then I paste _TSGetMainThread in the symbol field. Run the app but never hit a break point.


Edit: In a simple project on my other Mac still on 10.12 (same version of Xcode) I do hit the _TSGetMainThread breakpoint. Thought I was going crazy for awhile. Going to have to check out the project and debug it from there.

So when I hit the symbolic breakpoint, that background queue is running. That was it! I see where my mistake was, wasn't obvious at first. Thank you for your help.

!!! BUG: The current event queue and the main event queue are not the same. Events will not be handled correctly. This is probably because _TSGetMainThread was called for the first time off the main thread.
 
 
Q