Description
According to the header docs loadImageWithURLRequest can be called from any thread.
https://github.com/facebook/react-native/blob/0bb085c7b65527717a1c2750fadc0783c8da6b78/packages/react-native/Libraries/Image/RCTImageLoaderProtocol.h#L68
But the one time setup code has race condition and multiple threads can enter the setUp method:
https://github.com/facebook/react-native/blob/0bb085c7b65527717a1c2750fadc0783c8da6b78/packages/react-native/Libraries/Image/RCTImageLoader.mm#L159-L161
This could potentially lead to crashes like this: #33592
Steps to reproduce
The reproducer at https://github.com/mfazekas/RCTImageLoaderTheadSafety has a native objetive-c class exectuted that hammers RCTImageLoader from many threads at the same time. Sometimes some crash can be reproduced that way. (Note that once the [setUp] has been called the race condition is not observable so app needs to restarted).
React Native Version
0.75.1
Affected Platforms
Runtime - iOS
Output of npx react-native info
% npx react-native info
error: unknown command 'info'
(Did you mean init?)
% npx react-native -v
14.0.0
### Stacktrace or Logs
```text
One crash I was able to reproduce with reproduce is:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x600000c65140> was mutated while being enumerated.'
*** First throw call stack:
(
0 CoreFoundation 0x00000001804ac330 __exceptionPreprocess + 172
1 libobjc.A.dylib 0x0000000180086c58 objc_exception_throw + 72
2 CoreFoundation 0x00000001804ab758 +[__NSFastEnumerationEnumerator allocWithZone:] + 0
3 ReproducerApp 0x0000000101318938 __30-[RCTImageLoader dequeueTasks]_block_invoke + 1532
4 libdispatch.dylib 0x0000000103a53f40 _dispatch_call_block_and_release + 24
5 libdispatch.dylib 0x0000000103a55838 _dispatch_client_callout + 16
6 libdispatch.dylib 0x0000000103a5db2c _dispatch_lane_serial_drain + 912
7 libdispatch.dylib 0x0000000103a5e830 _dispatch_lane_invoke + 420
8 libdispatch.dylib 0x0000000103a6b240 _dispatch_root_queue_drain_deferred_wlh + 324
9 libdispatch.dylib 0x0000000103a6a7d4 _dispatch_workloop_worker_thread + 764
10 libsystem_pthread.dylib 0x0000000104223814 _pthread_wqthread + 284
11 libsystem_pthread.dylib 0x00000001042225d4 start_wqthread + 8
)
Customer is observing a different crash:
OS Version: iOS 16.2 (20C65) Report Version: 104
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Crashed Thread: 37
Application Specific Information:
release
Thread 37 Crashed:
0 libdispatch.dylib 0x365c34ab4 _os_object_release
1 Halter 0x2006f72c4 -[RCTImageLoader imageURLLoaderForURL:] (RCTImageLoader.mm:182)
2 Halter 0x2006f81b4 -[RCTImageLoader _loadImageOrDataWithURLRequest:size:scale:resizeMode:priority:attribution:progressBlock:partialLoadBlock:completionBlock:] (RCTImageLoader.mm:507)
3 Halter 0x2006fa64c -[RCTImageLoader loadImageWithURLRequest:size:scale:clipped:resizeMode:priority:attribution:progressBlock:partialLoadBlock:completionBlock:] (RCTImageLoader.mm:857)
4 Halter 0x2006f7a0c -[RCTImageLoader loadImageWithURLRequest:size:scale:clipped:resizeMode:priority:progressBlock:partialLoadBlock:completionBlock:] (RCTImageLoader.mm:388)
5 Halter 0x2006f7904 -[RCTImageLoader loadImageWithURLRequest:size:scale:clipped:resizeMode:progressBlock:partialLoadBlock:completionBlock:] (RCTImageLoader.mm:367)
6 Halter 0x20171b958 closure in RNMBXImageQueueOperation.start (RNMBXImageQueue.swift:72)
7 Halter 0x2003dfea8 thunk for closure
8 libdispatch.dylib 0x365c344b0 _dispatch_call_block_and_release
9 libdispatch.dylib 0x365c35fd8 _dispatch_client_callout
10 libdispatch.dylib 0x365c390c4 _dispatch_queue_override_invoke
11 libdispatch.dylib 0x365c47a68 _dispatch_root_queue_drain
12 libdispatch.dylib 0x365c48280 _dispatch_worker_thread2
13 libsystem_pthread.dylib 0x3f3122db8 _pthread_wqthread
Thread 29
0 libsystem_kernel.dylib 0x3d22e5aa8 __psynch_mutexwait
1 libsystem_pthread.dylib 0x3f312414c _pthread_mutex_firstfit_lock_wait
2 libsystem_pthread.dylib 0x3f312b30c _pthread_mutex_firstfit_lock_slow
3 libc++.1.dylib 0x373d209ec std::__1::mutex::lock
4 Halter 0x2006f72d8 [inlined] std::__1::unique_lock::unique_lock[abi:ue170006] (unique_lock.h:41)
5 Halter 0x2006f72d8 [inlined] std::__1::unique_lock::unique_lock[abi:ue170006] (unique_lock.h:40)
6 Halter 0x2006f72d8 -[RCTImageLoader imageURLLoaderForURL:] (RCTImageLoader.mm:186)
7 Halter 0x2006f81b4 -[RCTImageLoader _loadImageOrDataWithURLRequest:size:scale:resizeMode:priority:attribution:progressBlock:partialLoadBlock:completionBlock:] (RCTImageLoader.mm:507)
8 Halter 0x2006fa64c -[RCTImageLoader loadImageWithURLRequest:size:scale:clipped:resizeMode:priority:attribution:progressBlock:partialLoadBlock:completionBlock:] (RCTImageLoader.mm:857)
9 Halter 0x2006f7a0c -[RCTImageLoader loadImageWithURLRequest:size:scale:clipped:resizeMode:priority:progressBlock:partialLoadBlock:completionBlock:] (RCTImageLoader.mm:388)
10 Halter 0x2006f7904 -[RCTImageLoader loadImageWithURLRequest:size:scale:clipped:resizeMode:progressBlock:partialLoadBlock:completionBlock:] (RCTImageLoader.mm:367)
11 Halter 0x20171b958 closure in RNMBXImageQueueOperation.start (RNMBXImageQueue.swift:72)
12 Halter 0x2003dfea8 thunk for closure
13 libdispatch.dylib 0x365c344b0 _dispatch_call_block_and_release
14 libdispatch.dylib 0x365c35fd8 _dispatch_client_callout
15 libdispatch.dylib 0x365c390c4 _dispatch_queue_override_invoke
16 libdispatch.dylib 0x365c47a68 _dispatch_root_queue_drain
17 libdispatch.dylib 0x365c48280 _dispatch_worker_thread2
18 libsystem_pthread.dylib 0x3f3122db8 _pthread_wqthread
### Reproducer
https://github.com/mfazekas/RCTImageLoaderTheadSafety
### Screenshots and Videos
See: https://github.com/rnmapbox/maps/issues/3589
Description
According to the header docs
loadImageWithURLRequestcan be called from any thread.https://github.com/facebook/react-native/blob/0bb085c7b65527717a1c2750fadc0783c8da6b78/packages/react-native/Libraries/Image/RCTImageLoaderProtocol.h#L68
But the one time setup code has race condition and multiple threads can enter the
setUpmethod:https://github.com/facebook/react-native/blob/0bb085c7b65527717a1c2750fadc0783c8da6b78/packages/react-native/Libraries/Image/RCTImageLoader.mm#L159-L161
This could potentially lead to crashes like this: #33592
Steps to reproduce
The reproducer at https://github.com/mfazekas/RCTImageLoaderTheadSafety has a native objetive-c class exectuted that hammers RCTImageLoader from many threads at the same time. Sometimes some crash can be reproduced that way. (Note that once the [setUp] has been called the race condition is not observable so app needs to restarted).
React Native Version
0.75.1
Affected Platforms
Runtime - iOS
Output of
npx react-native infoCustomer is observing a different crash: