There's a very common case in our app where we crash due to code in GREYIdlingResourcePrettyPrint.m. We run against Detox 15.4.0.
Internally at Facebook we have an iOS react native module called 'RCTVideoView'. The code happens to do a call to setNeedsLayout during it's dealloc (that's probably not a good idea, but regardless, that's what happens today).
EarlGrey is intercepting calls to setNeedsLayout to track state.
Detox is intercepting these calls to track state here: https://github.com/wix/Detox/blob/f63ebce0bdc6b96df324a265d617b90a122b5fdd/detox/ios/Detox/GREYIdlingResourcePrettyPrint.m#L74
A call to __DTXDeallocSafeProxy initWithObject happens here, where the object is the view that is currently in the middle of deallocation.
During the init of __DTXDeallocSafeProxy, it tries to store the object into a weak property. https://github.com/wix/Detox/blob/f63ebce0bdc6b96df324a265d617b90a122b5fdd/detox/ios/Detox/GREYIdlingResourcePrettyPrint.m#L45
It looks like this objc_storeWeak throws bad alloc.
From all documentation I can find, objc_storeWeak is supposed to store nil into the weak property if the object is in the middle of deallocation. Though, this code seems to crash anyway. (https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-runtime-objc-storeweak)
Any ideas or thoughts on how to fix this?
cc @cs01
Here is my full stack trace:
```
Signal 4 was raised
(
0 Detox 0x000000011a41a984
_ZL16__DTXHandleCrashP11NSExceptionP8NSNumberP8NSString + 497
1 Detox 0x000000011a41a709 _ZL17__DTXHandleSignali + 59
2 libsystem_platform.dylib 0x00007fff52457b5d _sigtramp + 29
3 ??? 0x0000600000f709a0 0x0 + 105553132456352
4 libobjc.A.dylib 0x000000011b9fb0c2 _ZN11objc_object27sidetable_clearDeallocatingEv + 66
5 libobjc.A.dylib 0x000000011b9f34ca objc_destructInstance + 87
6 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
7 libxpc.dylib 0x0000000123f853b7 -[OS_xpc_object dealloc] + 47
8 libxpc.dylib 0x0000000123f75b9d _xpc_dictionary_node_free + 62
9 libxpc.dylib 0x0000000123f7320a _xpc_dictionary_dispose + 34
10 libxpc.dylib 0x0000000123f69fbf _xpc_dispose + 130
11 libxpc.dylib 0x0000000123f85399 -[OS_xpc_object dealloc] + 17
12 libsystem_trace.dylib 0x0000000123f30bbb _os_activity_stream_reflect + 696
13 libsystem_trace.dylib 0x0000000123f3c399 _os_log_impl_stream + 564
14 libsystem_trace.dylib 0x0000000123f3b90f _os_log_impl_flatten_and_send + 6347
15 libsystem_trace.dylib 0x0000000123f3a035 _os_log + 162
16 libsystem_trace.dylib 0x0000000123f3c923 _os_log_impl + 9
17 Detox 0x000000011a409cfa __dtx_log + 378
18 Detox 0x000000011a40a3d5 -[WebSocket sendAction:withParams:withMessageId:] + 317
19 Detox 0x000000011a4186cb -[DetoxManager notifyOnCrashWithDetails:] + 254
20 Detox 0x000000011a41aa46 _ZL16__DTXHandleCrashP11NSExceptionP8NSNumberP8NSString + 691
21 Detox 0x000000011a41a709 _ZL17__DTXHandleSignali + 59
22 libsystem_platform.dylib 0x00007fff52457b5d _sigtramp + 29
23 libobjc.A.dylib 0x000000011ba13020 _ZN12_GLOBAL__N_113SideTablesMapE + 3808
24 libsystem_kernel.dylib 0x00007fff523cf589 abort_with_payload_wrapper_internal + 0
25 libobjc.A.dylib 0x000000011b9fc1b7 _ZL12_objc_fatalvyyPKcP13__va_list_tag + 108
26 libobjc.A.dylib 0x000000011b9fc14b _ZL12_objc_fatalvyyPKcP13__va_list_tag + 0
27 libobjc.A.dylib 0x000000011b9f92b8 _ZL22defaultBadAllocHandlerP10objc_class + 0
28 libobjc.A.dylib 0x000000011b9fa866 objc_storeWeak + 489
29 Detox 0x000000011a40cd04 -[__DTXDeallocSafeProxy initWithObject:] + 109
30 Detox 0x000000011a40ce4a -[GREYAppStateTracker(PrettyPrint) _pp__trackState:forObject:] + 110
31 EarlGrey 0x0000000140e094e3 -[UIView(GREYAdditions) greyswizzled_setNeedsLayout] + 115
32 Twilight 0x000000010e8d42be -[RCTVideoView _setState:] + 94
33 Twilight 0x000000010e8d57b2 -[RCTVideoView _removePlayer] + 834
34 Twilight 0x000000010e8d2b08 -[RCTVideoView _reset] + 72
35 Twilight 0x000000010e8d2c9c -[RCTVideoView dealloc] + 44
36 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
37 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
38 libobjc.A.dylib 0x000000011b9f64c0 _object_remove_assocations + 239
39 libobjc.A.dylib 0x000000011b9f34c2 objc_destructInstance + 79
40 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
41 UIKitCore 0x000000012ec9d6c2 -[UIResponder dealloc] + 145
42 UIKit 0x00000001472e495c -[UIResponderAccessibility dealloc] + 55
43 UIKitCore 0x000000012f12531c -[UIView dealloc] + 981
44 Twilight 0x000000010eaf299f -[RCTView dealloc] + 191
45 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
46 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
47 libobjc.A.dylib 0x000000011b9f64c0 _object_remove_assocations + 239
48 libobjc.A.dylib 0x000000011b9f34c2 objc_destructInstance + 79
49 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
50 UIKitCore 0x000000012ec9d6c2 -[UIResponder dealloc] + 145
51 UIKit 0x00000001472e495c -[UIResponderAccessibility dealloc] + 55
52 UIKitCore 0x000000012f12531c -[UIView dealloc] + 981
53 Twilight 0x000000010eaf299f -[RCTView dealloc] + 191
54 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
55 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
56 libobjc.A.dylib 0x000000011b9f64c0 _object_remove_assocations + 239
57 libobjc.A.dylib 0x000000011b9f34c2 objc_destructInstance + 79
58 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
59 UIKitCore 0x000000012ec9d6c2 -[UIResponder dealloc] + 145
60 UIKit 0x00000001472e495c -[UIResponderAccessibility dealloc] + 55
61 UIKitCore 0x000000012f12531c -[UIView dealloc] + 981
62 Twilight 0x000000010eaf299f -[RCTView dealloc] + 191
63 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
64 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
65 libobjc.A.dylib 0x000000011b9f64c0 _object_remove_assocations + 239
66 libobjc.A.dylib 0x000000011b9f34c2 objc_destructInstance + 79
67 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
68 UIKitCore 0x000000012ec9d6c2 -[UIResponder dealloc] + 145
69 UIKit 0x00000001472e495c -[UIResponderAccessibility dealloc] + 55
70 UIKitCore 0x000000012f12531c -[UIView dealloc] + 981
71 Twilight 0x000000010eaf299f -[RCTView dealloc] + 191
72 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
73 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
74 libobjc.A.dylib 0x000000011b9f64c0 _object_remove_assocations + 239
75 libobjc.A.dylib 0x000000011b9f34c2 objc_destructInstance + 79
76 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
77 UIKitCore 0x000000012ec9d6c2 -[UIResponder dealloc] + 145
78 UIKit 0x00000001472e495c -[UIResponderAccessibility dealloc] + 55
79 UIKitCore 0x000000012f12531c -[UIView dealloc] + 981
80 Twilight 0x000000010eaf299f -[RCTView dealloc] + 191
81 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
82 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
83 libobjc.A.dylib 0x000000011b9f64c0 _object_remove_assocations + 239
84 libobjc.A.dylib 0x000000011b9f34c2 objc_destructInstance + 79
85 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
86 UIKitCore 0x000000012ec9d6c2 -[UIResponder dealloc] + 145
87 UIKit 0x00000001472e495c -[UIResponderAccessibility dealloc] + 55
88 UIKitCore 0x000000012f12531c -[UIView dealloc] + 981
89 Twilight 0x000000010eaf299f -[RCTView dealloc] + 191
90 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
91 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
92 libobjc.A.dylib 0x000000011b9f64c0 _object_remove_assocations + 239
93 libobjc.A.dylib 0x000000011b9f34c2 objc_destructInstance + 79
94 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
95 UIKitCore 0x000000012ec9d6c2 -[UIResponder dealloc] + 145
96 UIKit 0x00000001472e495c -[UIResponderAccessibility dealloc] + 55
97 UIKitCore 0x000000012f12531c -[UIView dealloc] + 981
98 Twilight 0x000000010eaf299f -[RCTView dealloc] + 191
99 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
100 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
101 libobjc.A.dylib 0x000000011b9f64c0 _object_remove_assocations + 239
102 libobjc.A.dylib 0x000000011b9f34c2 objc_destructInstance + 79
103 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
104 UIKitCore 0x000000012ec9d6c2 -[UIResponder dealloc] + 145
105 UIKit 0x00000001472e495c -[UIResponderAccessibility dealloc] + 55
106 UIKitCore 0x000000012f12531c -[UIView dealloc] + 981
107 Twilight 0x000000010eaf299f -[RCTView dealloc] + 191
108 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
109 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
110 libobjc.A.dylib 0x000000011b9f64c0 _object_remove_assocations + 239
111 libobjc.A.dylib 0x000000011b9f34c2 objc_destructInstance + 79
112 libobjc.A.dylib 0x000000011b9f994f -[NSObject dealloc] + 21
113 UIKitCore 0x000000012ec9d6c2 -[UIResponder dealloc] + 145
114 UIKit 0x00000001472e495c -[UIResponderAccessibility dealloc] + 55
115 UIKitCore 0x000000012f12531c -[UIView dealloc] + 981
116 Twilight 0x000000010eaf299f -[RCTView dealloc] + 191
117 CoreFoundation 0x000000011d128f7f -[__NSArrayM dealloc] + 415
118 libobjc.A.dylib 0x000000011b9fa0d6 _ZN11objc_object17sidetable_releaseEb + 174
119 libobjc.A.dylib 0x000000011b9fb75b _ZN19AutoreleasePoolPage12releaseUntilEPP11objc_object + 147
120 libobjc.A.dylib 0x000000011b9fb67a objc_autoreleasePoolPop + 199
121 CoreFoundation 0x000000011d234396 _CFAutoreleasePoolPop + 22
122 CoreFoundation 0x000000011d170cb1 __CFRunLoopRun + 2337
123 CoreFoundation 0x000000011d170066 CFRunLoopRunSpecific + 438
124 GraphicsServices 0x0000000126db4bb0 GSEventRunModal + 65
125 Detox 0x000000011a40f075 __detox_UIApplication_run + 365
126 UIKitCore 0x000000012ec70d4d UIApplicationMain + 1621
127 Twilight 0x000000010ed4e5c1 main + 113
128 libdyld.dylib 0x0000000123c4dc25 start + 1
)`
Thank you, will look soon.
Ah I found documentation which matches the behavior of objc_storeWeak crashing if the object being stored is in the middle of deallocation.
https://github.com/opensource-apple/objc4/blob/master/runtime/NSObject.mm#L360
The third template parameter 'CrashIfDeallocating' is true for objc_storeWeak.
While, it's "false" for objc_storeWeakOrNil. This would mean that using objc_storeWeakOrNil would allow us to dodge a crash in this scenario.
Interesting. I'm not entirely sure how to use objc_storeWeak/objc_storeWeakOrNil directly.
Would it simply mean objc_storeWeakOrNil(&_object, object);?
Perhaps just move __DTXDeallocSafeProxy into no-arc land and just call the init/store/load/destroy on my own.
Thanks a ton @LeoNatan
Cheers. Will release a version soon. Let me know how it works.
15.4.4
In our test runs we've had today, I haven't seen this crash anymore! I'll come back to this issue if i'm wrong. Thanks again!
Great, thanks for the followup!
Most helpful comment
15.4.4