Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Crash in user-initiated-qos.overcommit. What might create this queue?

I have an crash report from a live app:

Crashed: com.apple.root.user-initiated-qos.overcommit
0  libobjc.A.dylib                0x21d486c8 objc_release + 7
1  libobjc.A.dylib                0x21d493a9 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 388
2  libdispatch.dylib              0x22110739 _dispatch_root_queue_drain + 1896
3  libdispatch.dylib              0x2210ffcd _dispatch_worker_thread3 + 96
4  libsystem_pthread.dylib        0x222c5b29 _pthread_wqthread + 1024
5  libsystem_pthread.dylib        0x222c5718 start_wqthread + 8

The most useful piece of information seems to be the name of the queue that the crash occurred on: com.apple.root.user-initiated-qos.overcommit. I've checked all my code and I either use the main queue, a system background queue (i.e. not user-initiated-qos), or named queues that I create myself.

I do have other SDKs included with my app so there is fair possibility that those SDKs may be dispatching work onto this queue. But before I assume that this is the case I was wondering if there are any common reasons that iOS itself will dispatch work onto this queue, which may help me isolate areas of my codebase for closer inspection.

I understand from researching (WWDC 2015 - Session 718) that the user-initiated-qos quality of service setting may be automatically applied to a queue when work is dispatch_async onto a queue that doesn't have a specific 'Quality of Service' setting, from the main thread (user interactive qos). But as described above I don't think I am doing this as I name all my queues.

So does anyone know if or when iOS uses the com.apple.root.user-initiated-qos.overcommit queue?

like image 572
Rory O'Bryan Avatar asked May 24 '16 13:05

Rory O'Bryan


1 Answers

This is a default queue created by the system. Various UI components and system components dispatch blocks to this queue.

When you see a crash with _dispatch_root_queue_drain in the stack trace it means some block has already executed on that queue and the autorelease pool is being drained. Usually the crash is caused by releasing an already release object, it just so happens the "extra" release ends up attributed to the autorelease pool because it runs last.

The odds are that you've handed off an object to a system framework somewhere but it is getting over-released accidentally.

edit: Here are instructions for using NSZombie to track these down

like image 145
russbishop Avatar answered Sep 19 '22 14:09

russbishop