Random EXC_BAD_ACCESS crash in relationship_query.rb
So I keep getting random crashes when importing data using cdq and magicalrecord. MagicalRecord imports the data without any problems but then the app randomly crashes on this line https://github.com/infinitered/cdq/blob/master/motion/cdq/relationship_query.rb#L60. My code and console logs are below.
#feed.rb
class Feed < CDQManagedObject
...
def import_from_object(object, opts= {})
cdq.background(opts) do
self.MR_importFromObject(object, inContext: cdq.contexts.current)
feed = Feed.where(feed_id: object['id']).first
if feed
card_ids = object['cards'].valueForKey('id')
predicate = NSPredicate.predicateWithFormat('card_id IN %@', card_ids)
feed.cards.filterUsingPredicate(predicate) # bug seems to be related to this line
end
end
cdq.save(always_wait: true)
cdq.contexts.on(:main) { cdq.save }
end
...
end
Running rake command with NSZombieEnabled
$ bundle exec rake debug=1 NSZombieEnabled=YES MallocStackLogging=1
NameError: name 'run_one_line' is not defined
error: Ditch Parsing a die that is being parsed die: 0x00199c6c: DW_TAG_array_type (null)
error: Ditch Parsing a die that is being parsed die: 0x00199c6c: DW_TAG_array_type (null)
error: Ditch Parsing a die that is being parsed die: 0x00199c6c: DW_TAG_array_type (null)
Process 51705 resuming
Process 51705 stopped
* thread #8: tid = 0x1936f8f, 0x00000001012549d0 Ditch`RoxorCore::method_node_get(objc_method*, bool) + 160, queue = 'NSManagedObjectContext 0x11af4a200', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x00000001012549d0 Ditch`RoxorCore::method_node_get(objc_method*, bool) + 160
Ditch`RoxorCore::method_node_get:
-> 0x1012549d0 <+160>: movq (%rcx), %rcx
0x1012549d3 <+163>: testq %rcx, %rcx
0x1012549d6 <+166>: je 0x101254a10 ; <+224>
0x1012549d8 <+168>: movq 0x8(%rcx), %rax
Logs
System Integrity Protection: enabled
Crashed Thread: 10 Dispatch queue: NSManagedObjectContext 0x1177ddcb0
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
Exception Note: EXC_CORPSE_NOTIFY
Application Specific Information:
CoreSimulator 209.19 - Device: iPhone 6 - Runtime: iOS 9.3 (13E230) - DeviceType: iPhone 6
Thread 0:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x0000000108460f72 mach_msg_trap + 10
1 libsystem_kernel.dylib 0x00000001084603b3 mach_msg + 55
2 com.apple.CoreFoundation 0x00000001038fe434 __CFRunLoopServiceMachPort + 212
3 com.apple.CoreFoundation 0x00000001038fd88f __CFRunLoopRun + 1295
4 com.apple.CoreFoundation 0x00000001038fd0f8 CFRunLoopRunSpecific + 488
5 com.apple.GraphicsServices 0x0000000108d94ad2 GSEventRunModal + 161
6 com.apple.UIKit 0x0000000105a8af09 UIApplicationMain + 171
7 com.ditchllc.Ditch 0x000000010012c552 main + 146 (main.mm:16)
8 libdyld.dylib 0x000000010812292d start + 1
Thread 1:: Dispatch queue: com.apple.libdispatch-manager
0 libsystem_kernel.dylib 0x0000000108467ee2 kevent64 + 10
1 libdispatch.dylib 0x00000001080e37f0 _dispatch_mgr_invoke + 260
2 libdispatch.dylib 0x00000001080e358a _dispatch_mgr_thread + 54
Thread 2:: Dispatch queue: NSManagedObjectContext 0x11865d6d0
0 com.ditchllc.Ditch 0x000000010122bac9 std::__1::__hash_table<std::__1::__hash_value_type<unsigned long, ccache*>, std::__1::__unordered_map_hasher<unsigned long, std::__1::__hash_value_type<unsigned long, ccache*>, std::__1::hash<unsigned long>, true>, std::__1::__unordered_map_equal<unsigned long, std::__1::__hash_value_type<unsigned long, ccache*>, std::__1::equal_to<unsigned long>, true>, std::__1::allocator<std::__1::__hash_value_type<unsigned long, ccache*> > >::__rehash(unsigned long) + 233
1 com.ditchllc.Ditch 0x000000010126879a std::__1::__hash_table<std::__1::__hash_value_type<objc_method*, rb_vm_method_node*>, std::__1::__unordered_map_hasher<objc_method*, std::__1::__hash_value_type<objc_method*, rb_vm_method_node*>, std::__1::hash<objc_method*>, true>, std::__1::__unordered_map_equal<objc_method*, std::__1::__hash_value_type<objc_method*, rb_vm_method_node*>, std::__1::equal_to<objc_method*>, true>, std::__1::allocator<std::__1::__hash_value_type<objc_method*, rb_vm_method_node*> > >::__node_insert_unique(std::__1::__hash_node<std::__1::__hash_value_type<objc_method*, rb_vm_method_node*>, void*>*) + 426
2 com.ditchllc.Ditch 0x0000000101266d10 std::__1::unordered_map<objc_method*, rb_vm_method_node*, std::__1::hash<objc_method*>, std::__1::equal_to<objc_method*>, std::__1::allocator<std::__1::pair<objc_method* const, rb_vm_method_node*> > >::operator[](objc_method* const&) + 256
3 com.ditchllc.Ditch 0x00000001012549f5 RoxorCore::method_node_get(objc_method*, bool) + 261
4 com.ditchllc.Ditch 0x0000000101259d5f RoxorCore::copy_method(objc_class*, objc_method*, objc_class*) + 591
5 com.ditchllc.Ditch 0x0000000101259a35 rb_vm_copy_methods + 85
6 com.ditchllc.Ditch 0x000000010112d7a4 rb_include_module2 + 644
7 com.ditchllc.Ditch 0x0000000101155edd rb_extend_object + 285
8 com.ditchllc.Ditch 0x00000001011567a7 rb_mod_extend_object + 23
9 com.ditchllc.Ditch 0x000000010122ef85 rb_vm_dispatch + 6981
10 com.ditchllc.Ditch 0x0000000101222cbf rb_funcall + 1039
11 com.ditchllc.Ditch 0x0000000101156a8b rb_obj_extend + 251
12 com.ditchllc.Ditch 0x000000010122e565 rb_vm_dispatch + 4389
13 com.ditchllc.Ditch 0x000000010042a97c vm_dispatch + 1372
14 com.ditchllc.Ditch 0x000000010042eb66 rb_scope__extend_set:__ + 342 (relationship_query.rb:60)
15 com.ditchllc.Ditch 0x000000010122ef85 rb_vm_dispatch + 6981
16 com.ditchllc.Ditch 0x000000010043c6ec vm_dispatch + 1372
17 com.ditchllc.Ditch 0x0000000100444b8d rb_scope__relationshipByName:__ + 365 (managed_object.rb:218)
18 com.ditchllc.Ditch 0x0000000100444c38 __unnamed_53 + 40
19 com.ditchllc.Ditch 0x000000010001bd5e __59+[CoreDataQueryManagedObjectBase defineRelationshipMethod:]_block_invoke + 46 (CoreDataQueryManagedObjectBase.m:17)
20 CoreData 0x0000000103578e3c _PF_Handler_Public_GetProperty + 140
21 com.apple.Foundation 0x000000010494d6d5 NSKeyValueWillChangeBySetMutation + 129
22 com.apple.Foundation 0x00000001048c3a3e NSKeyValueWillChange + 383
23 com.apple.Foundation 0x000000010494d5f1 -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:withSetMutation:usingObjects:] + 557
24 CoreData 0x00000001035de702 _sharedIMPL_addObjectToSet_core + 162
25 com.apple.CoreFoundation 0x00000001038cb5cc __invoking___ + 140
26 com.apple.CoreFoundation 0x00000001038cb41e -[NSInvocation invoke] + 286
27 com.apple.CoreFoundation 0x000000010395ad26 -[NSInvocation invokeWithTarget:] + 54
28 com.ditchllc.Ditch 0x00000001000d9375 -[NSManagedObject(MagicalRecordDataImport) MR_setObject:forRelationship:] + 842 (NSManagedObject+MagicalDataImport.m:121)
29 com.ditchllc.Ditch 0x00000001000da4d0 __77-[NSManagedObject(MagicalRecordDataImport) MR_importValuesForKeysWithObject:]_block_invoke + 265 (NSManagedObject+MagicalDataImport.m:348)
30 com.ditchllc.Ditch 0x00000001000d9aa2 __96-[NSManagedObject(MagicalRecordDataImport) MR_setRelationship:relatedData:setRelationshipBlock:]_block_invoke + 84 (NSManagedObject+MagicalDataImport.m:200)
31 com.ditchllc.Ditch 0x00000001000d9928 -[NSManagedObject(MagicalRecordDataImport) MR_setRelationship:relatedData:setRelationshipBlock:] + 932 (NSManagedObject+MagicalDataImport.m:207)
32 com.apple.CoreFoundation 0x000000010390c6be __NSDictionaryEnumerate + 814
33 com.ditchllc.Ditch 0x00000001000d9d82 -[NSManagedObject(MagicalRecordDataImport) MR_setRelationships:forKeysWithObject:withBlock:] + 172 (NSManagedObject+MagicalDataImport.m:229)
34 com.ditchllc.Ditch 0x00000001000da29c -[NSManagedObject(MagicalRecordDataImport) MR_importValuesForKeysWithObject:establishRelationshipBlock:] + 250 (NSManagedObject+MagicalDataImport.m:326)
35 com.ditchllc.Ditch 0x00000001000da372 -[NSManagedObject(MagicalRecordDataImport) MR_importValuesForKeysWithObject:] + 143 (NSManagedObject+MagicalDataImport.m:351)
36 com.ditchllc.Ditch 0x00000001000da635 +[NSManagedObject(MagicalRecordDataImport) MR_importFromObject:inContext:] + 278 (NSManagedObject+MagicalDataImport.m:377)
37 com.ditchllc.Ditch 0x0000000100267ba3 __unnamed_117 + 147
38 com.ditchllc.Ditch 0x00000001007b6bcc vm_dispatch + 1372
39 com.ditchllc.Ditch 0x00000001007bbc96 rb_scope__import_from_object:__block__ + 406 (feed.rb:80)
40 com.ditchllc.Ditch 0x00000001012303fe vm_block_eval(RoxorVM*, rb_vm_block*, objc_selector*, unsigned long, int, unsigned long const*) + 1502
41 com.ditchllc.Ditch 0x000000010122e565 rb_vm_dispatch + 4389
42 com.ditchllc.Ditch 0x00000001003dc7ac vm_dispatch + 1372
43 com.ditchllc.Ditch 0x00000001003e1cda rb_scope__push:__block__ + 186 (context.rb:36)
44 com.ditchllc.Ditch 0x00000001012303fe vm_block_eval(RoxorVM*, rb_vm_block*, objc_selector*, unsigned long, int, unsigned long const*) + 1502
45 com.ditchllc.Ditch 0x000000010122e565 rb_vm_dispatch + 4389
46 com.ditchllc.Ditch 0x00000001003dc7ac vm_dispatch + 1372
47 com.ditchllc.Ditch 0x00000001003e600f rb_scope__save_stack__ + 431 (context.rb:303)
48 com.ditchllc.Ditch 0x000000010122ef85 rb_vm_dispatch + 6981
49 com.ditchllc.Ditch 0x00000001003dc7ac vm_dispatch + 1372
50 com.ditchllc.Ditch 0x00000001003e1b4d rb_scope__push:__ + 877 (context.rb:33)
51 com.ditchllc.Ditch 0x000000010122ef85 rb_vm_dispatch + 6981
52 com.ditchllc.Ditch 0x00000001003dc7ac vm_dispatch + 1372
53 com.ditchllc.Ditch 0x00000001003e522b rb_scope__background:__block__ + 139 (context.rb:242)
54 com.ditchllc.Ditch 0x00000001012303fe vm_block_eval(RoxorVM*, rb_vm_block*, objc_selector*, unsigned long, int, unsigned long const*) + 1502
55 com.ditchllc.Ditch 0x00000001003eac21 __unnamed_424 + 33
FWIW looks like relationshipByName is not thread safe and does cause random crash in multithreaded situations. Crude patch to workaround this
https://github.com/infinitered/cdq/compare/master...islandmagic:cdq:master
If someone else has a better way to handle this, would be great to hear.