Skip to content

Fixes issue related to heap corruption #1170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 21, 2017
Merged

Conversation

flovilmart
Copy link
Contributor

@flovilmart flovilmart commented Aug 16, 2017

  • a block was capturing self in dealloc through _stopMonitoring
  • this removed the retain cycle at dealloc

Fixes #1168

This wasn't crashing before as dealloc was never called (cycle). Now that dealloc is properly called, setting self.connected = YES was creating a heap corruption as the blocks were not able to correctly retain self for executing the setConnected: logic

@flovilmart flovilmart merged commit e4ddb1b into master Aug 21, 2017
@flovilmart flovilmart deleted the fix/1168-heapcorruption branch August 21, 2017 23:04
@QB3L
Copy link

QB3L commented Aug 22, 2017

I still see a lot of race conditions in this branch related to PFCommandCache and PFEventuallyQueue setConnected:]

Is this supposed to fix those issues?

@flovilmart
Copy link
Contributor Author

What do you mean by races? This branch fixes a heap corruption crash related to capturing self in an async block when deallocating.

@QB3L
Copy link

QB3L commented Aug 22, 2017

Here is an example of what I am seeing constantly.
Looking around for some other issues I found comments about LDS being deprecated? Is this the case for iOS? I didn't see anything in the README

If that is the case then just ignore my question :)
My models are simple enough that I can save them myself with sqlite directly

==================
WARNING: ThreadSanitizer: data race (pid=58906)
Write of size 1 at 0x7d1000012862 by thread T2 (mutexes: write M1031):
#0 -[BFTask setCompleted:] BFTask.m (Bolts:x86_64+0x104a7)
#1 -[BFTask trySetResult:] BFTask.m:302 (Bolts:x86_64+0xbc33)
#2 -[BFTaskCompletionSource setResult:] BFTaskCompletionSource.m:46 (Bolts:x86_64+0x10d07)
#3 __34-[PFEventuallyQueue setConnected:]_block_invoke PFEventuallyQueue.m:404 (Parse:x86_64+0x73040)
#4 __tsan::invoke_and_release_block(void*) :1206112 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6043b)
#5 _dispatch_client_callout :1206112 (libdispatch.dylib:x86_64+0x2b05b)

Previous read of size 1 at 0x7d1000012862 by thread T6 (mutexes: write M283582895120049968):
#0 -[BFTask waitUntilFinished] BFTask.m:528 (Bolts:x86_64+0xfbeb)
#1 -[BFTask(Private) waitForResult:withMainThreadWarning:] BFTask+Private.m:105 (Parse:x86_64+0x375c)
#2 -[BFTask(Private) waitForResult:] BFTask+Private.m:100 (Parse:x86_64+0x36ab)
#3 -[PFEventuallyQueue setConnected:] PFEventuallyQueue.m:414 (Parse:x86_64+0x72dfa)
#4 -[PFEventuallyQueue _startMonitoringNetworkReachability] PFEventuallyQueue.m:370 (Parse:x86_64+0x728d5)
#5 -[PFEventuallyQueue initWithDataSource:maxAttemptsCount:retryInterval:] PFEventuallyQueue.m:78 (Parse:x86_64+0x6c4b0)
#6 -[PFCommandCache initWithDataSource:coreDataSource:maxAttemptsCount:retryInterval:diskCachePath:diskCacheSize:] PFCommandCache.m:76 (Parse:x86_64+0x31d03)
#7 +[PFCommandCache newDefaultCommandCacheWithCommonDataSource:coreDataSource:cacheFolderPath:] PFCommandCache.m:60 (Parse:x86_64+0x31a48)
#8 -[ParseManager _newCommandCache] ParseManager.m:200 (Parse:x86_64+0xbeb3)
#9 __31-[ParseManager eventuallyQueue]_block_invoke ParseManager.m:172 (Parse:x86_64+0xb7fa)
#10 __tsan::invoke_and_release_block(void*) :1206112 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6043b)
#11 _dispatch_client_callout :1206112 (libdispatch.dylib:x86_64+0x2b05b)
#12 -[ParseManager eventuallyQueue] ParseManager.m:162 (Parse:x86_64+0xb3e1)
#13 __47-[ParseManager preloadDiskObjectsToMemoryAsync]_block_invoke ParseManager.m:448 (Parse:x86_64+0x13198)
#14 __37+[BFTask taskFromExecutor:withBlock:]_block_invoke BFTask.m:285 (Bolts:x86_64+0xb8b7)
#15 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke BFTask.m:412 (Bolts:x86_64+0xda9a)
#16 __tsan::invoke_and_release_block(void*) :1206112 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6043b)
#17 _dispatch_client_callout :1206112 (libdispatch.dylib:x86_64+0x2b05b)

Location is heap block of size 64 at 0x7d1000012840 allocated by thread T6:
#0 calloc :1206144 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x44222)
#1 class_createInstance :1206144 (libobjc.A.dylib:x86_64+0xfba0)
#2 +[BFTaskCompletionSource taskCompletionSource] BFTaskCompletionSource.m:31 (Bolts:x86_64+0x1095a)
#3 -[PFEventuallyQueue setConnected:] PFEventuallyQueue.m:393 (Parse:x86_64+0x72b31)
#4 -[PFEventuallyQueue _startMonitoringNetworkReachability] PFEventuallyQueue.m:370 (Parse:x86_64+0x728d5)
#5 -[PFEventuallyQueue initWithDataSource:maxAttemptsCount:retryInterval:] PFEventuallyQueue.m:78 (Parse:x86_64+0x6c4b0)
#6 -[PFCommandCache initWithDataSource:coreDataSource:maxAttemptsCount:retryInterval:diskCachePath:diskCacheSize:] PFCommandCache.m:76 (Parse:x86_64+0x31d03)
#7 +[PFCommandCache newDefaultCommandCacheWithCommonDataSource:coreDataSource:cacheFolderPath:] PFCommandCache.m:60 (Parse:x86_64+0x31a48)
#8 -[ParseManager _newCommandCache] ParseManager.m:200 (Parse:x86_64+0xbeb3)
#9 __31-[ParseManager eventuallyQueue]_block_invoke ParseManager.m:172 (Parse:x86_64+0xb7fa)
#10 __tsan::invoke_and_release_block(void*) :1206144 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6043b)
#11 _dispatch_client_callout :1206144 (libdispatch.dylib:x86_64+0x2b05b)
#12 -[ParseManager eventuallyQueue] ParseManager.m:162 (Parse:x86_64+0xb3e1)
#13 __47-[ParseManager preloadDiskObjectsToMemoryAsync]_block_invoke ParseManager.m:448 (Parse:x86_64+0x13198)
#14 __37+[BFTask taskFromExecutor:withBlock:]_block_invoke BFTask.m:285 (Bolts:x86_64+0xb8b7)
#15 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke BFTask.m:412 (Bolts:x86_64+0xda9a)
#16 __tsan::invoke_and_release_block(void*) :1206144 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6043b)
#17 _dispatch_client_callout :1206144 (libdispatch.dylib:x86_64+0x2b05b)

Mutex M1031 (0x7d180001fe78) created at:
#0 pthread_mutex_lock :1206000 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x34ace)
#1 recursive_mutex_tt::lock() :1206000 (libobjc.A.dylib:x86_64+0x10046)
#2 _dispatch_client_callout :1206000 (libdispatch.dylib:x86_64+0x2b05b)

Mutex M283582895120049968 is already destroyed.

Thread T2 (tid=1782772, running) created by thread T-1
[failed to restore the stack]

Thread T6 (tid=1782784, running) created by thread T-1
[failed to restore the stack]
Summary: ThreadSanitizer: data race BFTask.m in -[BFTask setCompleted:]

ThreadSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.

==================

@flovilmart
Copy link
Contributor Author

LDS isn't deprecated, the report is helpful for future improvements with Thread Sanitizer on, we'll investigate. Can you open an issue with the Thead sanitizer infos?

@QB3L
Copy link

QB3L commented Aug 22, 2017

Done @flovilmart thanks for the update on the deprecation.

@flovilmart
Copy link
Contributor Author

No problem! Thanks for reporting! Did you see anything else on the thread sanitizer on other parts of the SDK?

@QB3L
Copy link

QB3L commented Aug 22, 2017

I have not. But I'll keep my eyes open for any other stuff.

tkhoa87 added a commit to notabasement/Parse-SDK-iOS-OSX that referenced this pull request Aug 31, 2017
…1.15.2

* commit '37aee695cf654c519243adc2945161a089855029':
  ⚡ Release 1.15.2
  Fixes issue related to heap corruption (parse-community#1170)
  Fix parse-community#1162 - PFSubclassing.object() class method unavailable since XCode 9 beta 4 (parse-community#1164)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants