Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crash with NSManagedObject release: "objc_msgSend() selector name: _queueForDealloc"

I have been getting a strange crash reported by lots of users through HockeyApp with the following stack trace. It seems to have something to do with NSManagedObject being released in a different dispatch queue ... but I don't get any symbolication for where the problem might be. It seems like a memory management issue, but I'm using ARC so not sure how it would over-release an NSManagedObject.

This is the crash report I get (the main thread shows different traces at different times):

Code Type:       ARM-64
Parent Process:  launchd [1]

Date/Time:       2014-05-12T05:43:54Z
OS Version:      iPhone OS 7.0.6 (11B651)
Report Version:  104

Exception Type:  SIGSEGV
Exception Codes: SEGV_ACCERR at 0x1c3dbeb8
Crashed Thread:  2

Application Specific Information:
objc_msgSend() selector name: _queueForDealloc:

Thread 0:
0   CoreFoundation                       0x000000018e384618 CFNumberGetType + 0
1   CoreFoundation                       0x000000018e3333b8 _CFAppendXML0 + 2768
2   CoreFoundation                       0x000000018e333304 _CFAppendXML0 + 2588
3   CoreFoundation                       0x000000018e332268 _CFPropertyListCreateXMLData + 196
4   Foundation                           0x000000018ef152f4 -[NSDictionary(NSDictionary) writeToFile:atomically:] + 232
5   SimpleList                           0x00000001001ae48c __55-[SharedSettingController writeToContactsReferenceFile]_block_invoke (SharedSettingController.m:620)
6   libdispatch.dylib                    0x000000019a974420 _dispatch_call_block_and_release + 20
7   libdispatch.dylib                    0x000000019a9743e0 _dispatch_client_callout + 12
8   libdispatch.dylib                    0x000000019a97756c _dispatch_main_queue_callback_4CF + 340
9   CoreFoundation                       0x000000018e3e6d64 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
10  CoreFoundation                       0x000000018e3e50a4 __CFRunLoopRun + 1448
11  CoreFoundation                       0x000000018e325b38 CFRunLoopRunSpecific + 448
12  GraphicsServices                     0x0000000193d4b830 GSEventRunModal + 164
13  UIKit                                0x00000001913640e8 UIApplicationMain + 1152
14  SimpleList                           0x000000010006347c _mh_execute_header (main.m:18)
15  libdyld.dylib                        0x000000019a98faa0 start + 0

Thread 1:
0   libsystem_kernel.dylib               0x000000019aa71ac8 kevent64 + 8
1   libdispatch.dylib                    0x000000019a975d78 _dispatch_mgr_thread + 48

Thread 2 Crashed:
0   libobjc.A.dylib                      0x000000019a39f9d0 objc_msgSend + 16
1   CoreData                             0x000000018e13b284 -[NSManagedObject release] + 168
2   CoreData                             0x000000018e131154 -[_PFArray dealloc] + 96
3   libobjc.A.dylib                      0x000000019a3a13d4 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 520
4   libdispatch.dylib                    0x000000019a97b428 _dispatch_root_queue_drain + 440
5   libdispatch.dylib                    0x000000019a97b638 _dispatch_worker_thread2 + 72
6   libsystem_pthread.dylib              0x000000019ab09918 _pthread_wqthread + 352
7   libsystem_pthread.dylib              0x000000019ab097a8 start_wqthread + 0

Thread 3:
0   libsystem_kernel.dylib               0x000000019aa71cc0 mach_msg_trap + 8
1   CoreFoundation                       0x000000018e3e6cac __CFRunLoopServiceMachPort + 180
2   CoreFoundation                       0x000000018e3e4e3c __CFRunLoopRun + 832
3   CoreFoundation                       0x000000018e325b38 CFRunLoopRunSpecific + 448
4   Foundation                           0x000000018ef127fc +[NSURLConnection(Loader) _resourceLoadLoop:] + 344
5   Foundation                           0x000000018efa0770 __NSThread__main__ + 996
6   libsystem_pthread.dylib              0x000000019ab0c1b0 _pthread_body + 164
7   libsystem_pthread.dylib              0x000000019ab0c108 _pthread_start + 136
8   libsystem_pthread.dylib              0x000000019ab097b0 thread_start + 0

Thread 4:
0   libsystem_kernel.dylib               0x000000019aa8a76c __select + 8
1   libsystem_pthread.dylib              0x000000019ab0c1b0 _pthread_body + 164
2   libsystem_pthread.dylib              0x000000019ab0c108 _pthread_start + 136
3   libsystem_pthread.dylib              0x000000019ab097b0 thread_start + 0

Thread 5:
0   libsystem_kernel.dylib               0x000000019aa8ae74 __workq_kernreturn + 8
1   libsystem_pthread.dylib              0x000000019ab097a8 start_wqthread + 0

Thread 6:
0   libsystem_kernel.dylib               0x000000019aa8ae74 __workq_kernreturn + 8
1   libsystem_pthread.dylib              0x000000019ab097a8 start_wqthread + 0

Thread 7:
0   libsystem_kernel.dylib               0x000000019aa8ae74 __workq_kernreturn + 8
1   libsystem_pthread.dylib              0x000000019ab097a8 start_wqthread + 0

Thread 2 crashed with ARM-64 Thread State:
    pc: 0x000000019a39f9d0     fp: 0x0000000102b479c0     sp: 0x0000000102b479a0     x0: 0x00000001782451f0 
    x1: 0x000000018e2eeb56     x2: 0x00000001705336a0     x3: 0x000000019aac3d18     x4: 0x0000000000000001 
    x5: 0x0000000000000010     x6: 0x000000017013f900     x7: 0x0000000000000000     x8: 0x000000019ad5bdb8 
    x9: 0x000000001c3dbea8    x10: 0x0000000000000000    x11: 0x000000230000003f    x12: 0x000000014f073410 
   x13: 0xbadd5bcc1c3dbead    x14: 0xffffffffffffffff    x15: 0x0000000000000001    x16: 0x000000019a39f9c0 
   x17: 0x000000018e13b1d8    x18: 0x0000000000000000    x19: 0x00000001705336a0    x20: 0x000000019ad7b000 
   x21: 0x000000019adc9200    x22: 0x000000019ad7b000    x23: 0x0000000000000715    x24: 0x0000000000000010 
   x25: 0x0000000102a64038    x26: 0xa3a3a3a3a3a3a3a3    x27: 0x0000000000000001    x28: 0x0000000000000000 
    lr: 0x000000018e13b284   cpsr: 0x0000000020000000 

At launch, I do initiate a couple of dispatch queues to do some background work (they use a separate MOC to load managed objects and process them), so those might be responsible, but the queues are labelled in my app, and the stack trace doesn't seem to show which queue is responsible (if it is my own queues). I've run the app with NSZombies enabled but that doesn't help. I have also ran the static analysis tool, and that doesn't turn up anything.

Any ideas what might be causing this problem, and what I can do to debug it?

EDIT:

I'm pretty sure I can isolate the problem area down to a piece of code that gets called after launching the app:

SLAppDelegate *delegate = (SLAppDelegate *) [[UIApplication sharedApplication] delegate];
dispatch_async(delegate.coreDataController.filterMainQueue, ^{

   NSManagedObjectContext *backgroundContextImage = [[NSManagedObjectContext alloc] init];
   [backgroundContextImage setPersistentStoreCoordinator: delegate.coreDataController.persistentStoreCoordinator];
   NSArray *items = [Person getAllPersonsWithContext: backgroundContextImage];
   // possibly update some of the items
   dispatch_async(dispatch_get_main_queue(), ^{

      // writes the file inside another dispatch_asyn(dispatch_get_main_queue) 
      [[SharedSettingController sharedSettings] writeToContactsReferenceFile];
   };
});

I'm just not sure what is wrong with this. It works fine 99% of the time. But that 1% is causing a few crashes that I'd love to get resolved.

like image 269
Z S Avatar asked May 14 '14 00:05

Z S


1 Answers

We hit into a a similar issue when using a private managed object context inside an NSOperation and we ended up working around it by weakifying any parameters and using a private @autoreleasepool. I'll elaborate further below.

Our current set up has an NSOperationQueue which has a long running calculation we do in the background. The operation first creates a private managed object context with the parent set as the main object context and goes and fetches its objects.

In the mean time, we have a separate NSOperationQueue elsewhere that syncs down new data from our server, potentially adding, updating, or removing objects used by our calculation operation.

We first saw a bunch of these crashes out in the wild and the only way to repro it locally is to have both calculation and sync operations run continuously and after 5-10 minutes, we would see a crash similar to one of the below:

Thread : Crashed: background queue :: NSOperation 0x18f43c90
0  libobjc.A.dylib                0x36f11f46 objc_msgSend + 5
1  CoreData                       0x2928408f -[NSManagedObject release] + 166
2  CoreData                       0x2927b4d7 -[_PFArray dealloc] + 94
3  libobjc.A.dylib                0x36f201a9 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 404
4  CoreFoundation                 0x294713a9 _CFAutoreleasePoolPop + 16
5  Foundation                     0x2a1b6453 -[__NSOperationInternal _start:] + 1058
6  Foundation                     0x2a25b44b __NSOQSchedule_f + 186
7  libdispatch.dylib              0x3746d651 _dispatch_queue_drain + 952
8  libdispatch.dylib              0x3746809d _dispatch_queue_invoke + 84
9  libdispatch.dylib              0x3746eba1 _dispatch_root_queue_drain + 320
10 libdispatch.dylib              0x3746fcd7 _dispatch_worker_thread3 + 94
11 libsystem_pthread.dylib        0x375c6e31 _pthread_wqthread + 668


Thread : Crashed: background queue :: NSOperation 0x1db59e80
0  libsystem_kernel.dylib         0x3722edfc __pthread_kill + 8
1  libsystem_pthread.dylib        0x372acd37 pthread_kill + 62
2  libsystem_c.dylib              0x371ce909 abort + 76
3  libsystem_malloc.dylib         0x37258331 szone_size
4  libobjc.A.dylib                0x36bf1621 object_dispose + 20
5  CoreData                       0x28ec571d -[_PFManagedObjectReferenceQueue dealloc] + 80
6  CoreData                       0x28e5630f -[NSManagedObject dealloc] + 166
7  CoreData                       0x28e55217 -[_PFManagedObjectReferenceQueue _queueForDealloc:] + 246
8  CoreData                       0x28e5508f -[NSManagedObject release] + 166
9  CoreData                       0x28e4c4d7 -[_PFArray dealloc] + 94
10 libobjc.A.dylib                0x36c031a9 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 404
11 CoreFoundation                 0x29042149 _CFAutoreleasePoolPop + 16
12 Foundation                     0x29d88c23 -[__NSOperationInternal _start:] + 1058
13 Foundation                     0x29e2dc1b __NSOQSchedule_f + 186
14 libdispatch.dylib              0x371505b1 _dispatch_queue_drain + 952
15 libdispatch.dylib              0x3714af85 _dispatch_queue_invoke + 84
16 libdispatch.dylib              0x37151b9b _dispatch_root_queue_drain + 338
17 libdispatch.dylib              0x37152cd7 _dispatch_worker_thread3 + 94
18 libsystem_pthread.dylib        0x372a9e31 _pthread_wqthread + 668


Thread : Crashed: NSOperationQueue Serial Queue
0  libsystem_kernel.dylib         0x396871f0 __pthread_kill + 8
1  libsystem_pthread.dylib        0x396ef7b7 pthread_kill + 58
2  libsystem_c.dylib              0x39637ff9 abort + 76
3  libsystem_malloc.dylib         0x396aed25 szone_size
4  libobjc.A.dylib                0x390d93a9 object_dispose + 20
5  CoreData                       0x2e3d4081 -[_PFManagedObjectReferenceQueue dealloc] + 80
6  CoreData                       0x2e3655b7 -[NSManagedObject dealloc] + 166
7  CoreData                       0x2e364501 -[_PFManagedObjectReferenceQueue _queueForDealloc:] + 244
8  CoreData                       0x2e36437d -[NSManagedObject release] + 164
9  CoreData                       0x2e35b867 -[_PFArray dealloc] + 94
10 libobjc.A.dylib                0x390e20d3 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 358
11 CoreFoundation                 0x2e5294c1 _CFAutoreleasePoolPop + 16
12 Foundation                     0x2ef29999 -[__NSOperationInternal _start:] + 1064
13 Foundation                     0x2efcd745 __NSOQSchedule_f + 60
14 libdispatch.dylib              0x395c0cbd _dispatch_queue_drain + 488
15 libdispatch.dylib              0x395bdc6f _dispatch_queue_invoke + 42
16 libdispatch.dylib              0x395c15f1 _dispatch_root_queue_drain + 76
17 libdispatch.dylib              0x395c18dd _dispatch_worker_thread2 + 56
18 libsystem_pthread.dylib        0x396ecc17 _pthread_wqthread + 298

We reviewed the code multiple times and was not able to determine why it was crashing. We tried enabling NSZombies, but would run out of memory long before we could get a repro.

What we ended up doing is the following 2 things:

@autoreleasepool

Inside our [privateObjectContext performBlockAndWait:^{…}] which resides inside our NSOperationBlock, we wrapped all the code inside an @autoreleasepool{…}. That way all NSManagedObjects retrieved during that block of code will be mark for release before leaving the performBlockAndWait.

weakify/strongify

Any parameters that include NSManagedObjects were weakify before passing it into the block, and strongify once in the block. This way since we no longer have a strong reference to them, they can be released if they become out of date while we wait for the NSOperation to start. Here's a good article on how weakify/strongify works: http://blog.aceontech.com/post/111694918560/weakifyself-a-more-elegant-solution-to

like image 110
Toland Hon Avatar answered Nov 06 '22 20:11

Toland Hon