react-native: [iOS] Crash in [RCTModuleData setUpMethodQueue]
I’m looking for a squashing bug in an iOS app that I can’t work out/reproduce. I am getting a logged error of
Selector name found in current argument registers: retain
This only seems to happen on iOS devices with 9.3 (Currently one of our top crashes in our application)
Log file for crash:
Thread 19 Crashed:
0 libdispatch.dylib 0x0000000181c02534 _os_object_retain + 72
1 libobjc.A.dylib 0x0000000181834128 objc_storeStrong + 40
2 libobjc.A.dylib 0x000000018181a908 object_setIvar + 272
3 Foundation 0x0000000182ac36e4 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 264
4 myapp 0x00000001007a4908 -[RCTModuleData setUpMethodQueue] (RCTModuleData.m:186)
5 myapp 0x00000001007a43f8 -[RCTModuleData setUpInstanceAndBridge] (RCTModuleData.m:120)
6 myapp 0x00000001007a4a6c -[RCTModuleData instance] (RCTModuleData.m:222)
7 myapp 0x000000010079e2b4 -[RCTBatchedBridge moduleForName:] (RCTBatchedBridge.m:216)
8 myapp 0x00000001007b4660 -[RCTBridge moduleForClass:] (RCTBridge.m:199)
9 myapp 0x000000010074e254 __100-[RCTImageLoader loadImageOrDataWithURLRequest:size:scale:resizeMode:progressBlock:completionBlock:]_block_invoke.142 (RCTImageLoader.m:415)
10 libdispatch.dylib 0x0000000181c014bc _dispatch_call_block_and_release + 20
11 libdispatch.dylib 0x0000000181c0147c _dispatch_client_callout + 12
12 libdispatch.dylib 0x0000000181c0d4c0 _dispatch_queue_drain + 860
13 libdispatch.dylib 0x0000000181c04f80 _dispatch_queue_invoke + 460
14 libdispatch.dylib 0x0000000181c0147c _dispatch_client_callout + 12
15 libdispatch.dylib 0x0000000181c0f914 _dispatch_root_queue_drain + 2136
16 libdispatch.dylib 0x0000000181c0f0b0 _dispatch_worker_thread3 + 108
17 libsystem_pthread.dylib 0x0000000181e19470 _pthread_wqthread + 1088
18 libsystem_pthread.dylib 0x0000000181e19020 start_wqthread + 0
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 3
- Comments: 37 (14 by maintainers)
Commits related to this issue
- Add changes proposed in https://github.com/facebook/react-native/issues/9334 to help with RCTImageLoader.m crashes. — committed to mikelambert/react-native by mikelambert 8 years ago
what’s the status on this?
So the RCTImageLoader crashes persist despite hardier
strongSelf
andweakSelf
checking, as well as into0.33.0-rc0
’s changes with the image loading classes.In current testing, it seems like this block is the culprit:
This is in
RCTImageLoader.m
, and in the methods:_loadImageOrDataWithURLRequest:size:scale:resizeMode:progressBlock:completionBlock
loadImageWithURLRequest:size:scale:clipped:resizeMode:progressBlock:completionBlock
The call stack flows from
RCTImageView::reloadImage
->RCTImageView::cancelImageLoad
-> those methods.The following lines will throw an EXC_BAD_ACCESS exception:
cancelLoad = nil;
OSAtomicOr32Barrier(1, &cancelled);
throws the exception as well.cancelLoad()
will throw it as wellThis is reproducible, but not pinned down to an exact set of steps that will make it crash guaranteed. We have a ListView with a large number of rows in which a
<Text>
component is wrapping a remotely loaded<Image>
component. This crash happens basically every time after scrolling quickly through the list, but not on a certain row or image url. That’s why it’s quasi-reproducible.Ideas:
Setting a property to nil that has already been dereferenced, will cause an EXC_BAD_ACCESS exception. Obviously this property is being released, but where and why that can happen is still unclear. My current idea is that the app is experiencing memory pressure and pruning views, which are still loading and holding references to the callback blocks, and then the app crashes doing what it thinks it should do.
I’m not sure who to ping on this, but I’m going to ping @brentvatne since he seems to be all over the place in the issues here. Sorry if this is not your area Brent, but maybe you could point us in the right direction here?
We are testing some block changes, and will update with results from the newest build.
We are transitioning the code that looks like this:
to this:
Doing this seems to fix it while testing, but this is really a huge problem in memory starved cases that are harder to debug and test in house. We really only started seeing these crashes once the app was out in production and crash reports started arriving in droves.
Our theory behind this is that there are several places where weak refs are being treated like strong refs. And also a series of places where things were not being null-checked. We are in the process of testing a patch: https://github.com/Curse/react-native/commit/bdf1354f67e872bcbaff45eba050d93ba8e15c4a Apply at your own risk, obviously.
@Griffosx I believe you’re seeing this “work” because technically the image has already been downloaded at that point.
There’s a
_pendingImageSource
and an_imageSource
and I believe the problem comes in play when you call[self cancelImageLoad]
while it is still in the process of loading. So with your fix, it just continues loading all the way through instead of removing the network task from the queue.It looks like there have been two commits to master that potentially deal with this problem.
The first one is slated for
0.35
release, and the second is in master and most likely to be added to0.36
.The first fix “sounds” like it’s correct via the commit description and reasoning. I’m going to add these two commit changes to our current fork and see if we can get the app to crash or not.
The issue is not resolved in 0.34.1 After a quick investigation I think I found what causes the problem (in my case). In very short, when an image goes out of the screen and it’s still loading sometimes the app crashes.
Workoround In
RCTImageView.m
replace in the methoddidMoveToWindow
the line:[self cancelImageLoad];
withif (_imageSource.request.URL.absoluteString) { [self cancelImageLoad]; }
With this modification my crashes vanishedNote: I don’t know exactly why sometimes the imagesSource is
nil
, I only noticed that this happens. Also, I’m quite sure that my modification doesn’t hurt the system, because that line is only an optimization, it can be commented also without problem.@javache thanks for the great news, I’ll update to the 0.34 stable version asap and release a new app version in the following week(s). I will monitor our crashes, if there are any, and let you know if I can verify the fix.
@bennyguitar We are seeing this crash disappear at FB with the latest version of React Native. Your patch can cause the scenario where items are cancelled multiple times, since cancelLoad is never nilled out.
My use case made it very easy to reproduce - this change fixes it thanks @bennyguitar !!!
I met the same crash.