Skip to content
This repository has been archived by the owner on Mar 16, 2019. It is now read-only.

Fix iOS initialization race condition #499

Merged
merged 1 commit into from
Aug 23, 2017
Merged

Conversation

mbarbon
Copy link

@mbarbon mbarbon commented Aug 22, 2017

We have a crash in our application, and based on our analysis the culprit is a
race condition in RNFetchBlobNetwork initialization.

Crashing thread:

    Crashed: com.apple.root.default-qos
0  libobjc.A.dylib                0x10416bacb objc_msgSend + 11
1  Foundation                     0x103d3b644 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] + 153
2  Foundation                     0x103c23f8c -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 61
3  Foundation                     0x103c23f3a -[NSOperationQueue setMaxConcurrentOperationCount:] + 198
4  prymr                          0x100d579aa -[RNFetchBlobNetwork init] (RNFetchBlobNetwork.m:112)
5  prymr                          0x100d63a73 __65-[RNFetchBlob fetchBlob:taskId:method:url:headers:body:callback:]_block_invoke (RNFetchBlob.m:131)
6  prymr                          0x100d6006b __85+[RNFetchBlobReqBuilder buildOctetRequest:taskId:method:url:headers:body:onComplete:]_block_invoke (RNFetchBlobReqBuilder.m:178)
7  libdispatch.dylib              0x107511585 _dispatch_call_block_and_release + 12

While a second thread is running:

com.apple.root.default-qos
0  libsystem_kernel.dylib         0x107891c22 __psynch_mutexwait + 10
1  libsystem_pthread.dylib        0x1078c6dfa _pthread_mutex_lock_wait + 100
2  libsystem_pthread.dylib        0x1078c4519 _pthread_mutex_lock_slow + 285
3  Foundation                     0x103d3b615 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] + 106
4  Foundation                     0x103c23f8c -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 61
5  Foundation                     0x103c23f3a -[NSOperationQueue setMaxConcurrentOperationCount:] + 198
6  prymr                          0x100d579aa -[RNFetchBlobNetwork init] (RNFetchBlobNetwork.m:112)
7  prymr                          0x100d63a73 __65-[RNFetchBlob fetchBlob:taskId:method:url:headers:body:callback:]_block_invoke (RNFetchBlob.m:131)
8  prymr                          0x100d6006b __85+[RNFetchBlobReqBuilder buildOctetRequest:taskId:method:url:headers:body:onComplete:]_block_invoke (RNFetchBlobReqBuilder.m:178)
9  libdispatch.dylib              0x107511585 _dispatch_call_block_and_release + 12

The patch just adds a dumb double-synchronization to the initialization.

We have a crash in our application, and based on our analysis the culprit is a
race condition in RNFetchBlobNetwork initialization.

Crashing thread:

        Crashed: com.apple.root.default-qos
	0  libobjc.A.dylib                0x10416bacb objc_msgSend + 11
	1  Foundation                     0x103d3b644 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] + 153
	2  Foundation                     0x103c23f8c -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 61
	3  Foundation                     0x103c23f3a -[NSOperationQueue setMaxConcurrentOperationCount:] + 198
	4  prymr                          0x100d579aa -[RNFetchBlobNetwork init] (RNFetchBlobNetwork.m:112)
	5  prymr                          0x100d63a73 __65-[RNFetchBlob fetchBlob:taskId:method:url:headers:body:callback:]_block_invoke (RNFetchBlob.m:131)
	6  prymr                          0x100d6006b __85+[RNFetchBlobReqBuilder buildOctetRequest:taskId:method:url:headers:body:onComplete:]_block_invoke (RNFetchBlobReqBuilder.m:178)
	7  libdispatch.dylib              0x107511585 _dispatch_call_block_and_release + 12

While a second thread is running:

	com.apple.root.default-qos
	0  libsystem_kernel.dylib         0x107891c22 __psynch_mutexwait + 10
	1  libsystem_pthread.dylib        0x1078c6dfa _pthread_mutex_lock_wait + 100
	2  libsystem_pthread.dylib        0x1078c4519 _pthread_mutex_lock_slow + 285
	3  Foundation                     0x103d3b615 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] + 106
	4  Foundation                     0x103c23f8c -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 61
	5  Foundation                     0x103c23f3a -[NSOperationQueue setMaxConcurrentOperationCount:] + 198
	6  prymr                          0x100d579aa -[RNFetchBlobNetwork init] (RNFetchBlobNetwork.m:112)
	7  prymr                          0x100d63a73 __65-[RNFetchBlob fetchBlob:taskId:method:url:headers:body:callback:]_block_invoke (RNFetchBlob.m:131)
	8  prymr                          0x100d6006b __85+[RNFetchBlobReqBuilder buildOctetRequest:taskId:method:url:headers:body:onComplete:]_block_invoke (RNFetchBlobReqBuilder.m:178)
	9  libdispatch.dylib              0x107511585 _dispatch_call_block_and_release + 12

The patch just adds a dumb double-synchronization to the initialization.
@jackdoe
Copy link

jackdoe commented Aug 22, 2017

also related to #295

@lll000111 lll000111 requested a review from wkh237 August 22, 2017 15:08
@wkh237 wkh237 merged commit 9abb4eb into wkh237:0.10.9 Aug 23, 2017
@jkvim
Copy link

jkvim commented Sep 13, 2017

@wkh237 Could you publish this, I think this solve my issue. Thanks :)

@kelset
Copy link

kelset commented Oct 5, 2017

Sorry to ping you again @wkh237 but can you release a new version with this patch? The issue #295 keeps happening to my users even in 0.48 and seems like this PR may fix it once and for all :)
(edit: moreover this issue doesn't appear on master so I can't point there ><' )

@mbarbon
Copy link
Author

mbarbon commented Oct 6, 2017

@kelset @jkvim a workaround is to make a single dummy request early in the app initialization (event something like requesting www.google.com with a 1 ms timeout and ignoring success/falire will be enough)

jiabinxu added a commit to jiabinxu/react-native-fetch-blob that referenced this pull request Nov 19, 2017
danielsuo added a commit to danielsuo/react-native-fetch-blob that referenced this pull request Feb 13, 2018
* upstream/0.10.9:
  Fixed problem with type casting (wkh237#513)
  My proposed 0.10.9 changes (wkh237#489)
  wkh237#268 Cancelled task should not trigger `then` promise function
  Add ability to cancel android DownloadManager fetches (wkh237#502)
  Fix iOS initialization race condition (wkh237#499)
  prevent UIApplication methods from being called on background thread (wkh237#486)
  Implemenet fs.hash() -- wkh237#439 "Feature: Calculate file hash" (wkh237#476)
  I forgot one error string for the Android readFile() method (wkh237#475)
  Fix for wkh237#467 (wkh237#472)
  Fix for issue wkh237#468, wkh237#461, wkh237#460 and minor cleanup (wkh237#469)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants