Apparent dealloc error after Swift 5/Xcode 10.3 upgrade
adjustnox opened this issue · 10 comments
Hello,
I am taking over a project, and after making the upgrade to Xcode 10.3, Brightfutures is crashing every time. Any help offered would be appreciated. I am attaching the Stacktrace and screenshots of the code in question.
- thread #25, queue = 'NSOperationQueue 0x600000c6caa0 (QOS: UNSPECIFIED)', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x000000010c942d68 libswiftCore.dylibswift_getAssociatedTypeWitnessSlowImpl(swift::MetadataRequest, swift::TargetWitnessTable<swift::InProcess>*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*) + 200 frame #1: 0x000000010c941308 libswiftCore.dylib
swift_getAssociatedTypeWitness + 152
frame #2: 0x000000010a0164c9 Kit`MutableAsyncType<>.success(value=, self=) at :0- frame #3: 0x000000010a0174ab Kit
Promise.success(value=10745 bytes, self=0x0000600000c75ee0) at Promise.swift:49:16 frame #4: 0x0000000109fd5ea5 Kit
closure #1 in URLSessionRequestHandler.handleRequest(data=10745 bytes, response=0x0000600000c427e0, error=nil, promise=0x0000600000c75ee0) at URLSessionRequestHandler.swift:20:25
frame #5: 0x0000000109fd5fec Kitpartial apply for closure #1 in URLSessionRequestHandler.handleRequest(_:) at <compiler-generated>:0 frame #6: 0x0000000109fd6116 Kit
thunk for @escaping @callee_guaranteed (@guaranteed Data?, @guaranteed NSURLResponse?, @guaranteed Error?) -> () at :0
frame #7: 0x00000001038d72b1 DAILYLOOK__InstrumentDataTaskWithRequestCompletionHandler_block_invoke.81 + 218 frame #8: 0x00000001038d72b1 DAILYLOOK
__InstrumentDataTaskWithRequestCompletionHandler_block_invoke.81 + 218
frame #9: 0x000000010aa34178 CFNetwork__75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 19 frame #10: 0x000000010aa4ac56 CFNetwork
__49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 172
frame #11: 0x0000000106d7f33e Foundation__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7 frame #12: 0x0000000106d7f246 Foundation
-[NSBlockOperation main] + 68
frame #13: 0x0000000106d7c120 Foundation-[__NSOperationInternal _start:] + 688 frame #14: 0x0000000106d81e87 Foundation
__NSOQSchedule_f + 227
frame #15: 0x000000010d30cd7f libdispatch.dylib_dispatch_call_block_and_release + 12 frame #16: 0x000000010d30ddb5 libdispatch.dylib
_dispatch_client_callout + 8
frame #17: 0x000000010d310c95 libdispatch.dylib_dispatch_continuation_pop + 552 frame #18: 0x000000010d31008f libdispatch.dylib
_dispatch_async_redirect_invoke + 849
frame #19: 0x000000010d31e632 libdispatch.dylib_dispatch_root_queue_drain + 351 frame #20: 0x000000010d31efca libdispatch.dylib
_dispatch_worker_thread2 + 130
frame #21: 0x000000010d6f66b3 libsystem_pthread.dylib_pthread_wqthread + 583 frame #22: 0x000000010d6f63fd libsystem_pthread.dylib
start_wqthread + 13
- frame #3: 0x000000010a0174ab Kit
did you have a strong reference on the Future
returned by handleRequest
?
Sorry to hear you're encountering issues. I can't reproduce the issue myself, it would be helpful if you could provide a crashing test case in a PR if possible.
Could you also try rewriting the method to not use a Promise
(as shown at https://github.com/Thomvis/BrightFutures#providing-futures) to see if the crash still happens?
I removed all Promises (there were several, nested). Once I switched to using only futures, the crashes stopped.
Glad to hear. Would still love to have a reproducing test case to get this issue fixed, so if you have any insights you can share please do :)
I have a project I am working on to do just that. Will post back when I get it in place.
We're getting this exact same issue happening after the Swift 5/Xcode 11/BrightFutures 8.0.0 upgrade.
@adjustnox any luck on getting the reproducible project set up?
@Thomvis We tried converting the following block to Futures:
{
private var computeFeedItemsTask:Future<[ContentItemVM], Never>?
// FAILING METHOD
private func computeFeedItems() -> Future<[ContentItemVM], Never> {
...
let existingComputation:Future<[ContentItemVM], Never> = computeFeedItemsTask ?? Future( value: [ContentItemVM]() )
// FAILING LINE
let existingComputationPart:String = (existingComputation.isCompleted) ? "finished" : "in progress...."
...
computeFeedItemsTask = existingComputation.map( computeFeedItemsQueue.context ){ _ /*(_:[FeedItemVM])*/ -> /*Future<*/[ContentItemVM]/*, NoError>*/ in
...
return feedItems
}.onSuccess( DispatchQueue.main.context ){ (feedItems:[ContentItemVM]) in
...
}
}
}
STACK TRACE:
#0 0x0000000112ebf94f in swift_getAssociatedTypeWitnessSlowImpl(swift::MetadataRequest, swift::TargetWitnessTable<swift::InProcess>*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*, swift::TargetProtocolRequirement<swift::InProcess> const*) ()
#2 0x000000010ee8edaf in AsyncType.isCompleted.getter ()
#3 0x000000010eb491f6 in FeedController.computeFeedItems() at /Users/marchy/Documents/Projects/Happ/Mobile-iOS/Code/Happ.Mobile/Controllers/FeedController.swift:2090
#4 0x000000010eb2c8f5 in FeedController.viewDidLoad() at /Users/marchy/Documents/Projects/Happ/Mobile-iOS/Code/Happ.Mobile/Controllers/FeedController.swift:936
by changing the .map{...}
call above to computeFeedItemsTask = Future { complete in DispatchQueue.global().async { ... }}
as suggested in the docs, but it actually doesn't even run that far, since existingComputation
fails beforehand when trying to access existingComputation.isCompleted
when set with its initial empty array value (Future( value: [ContentItemVM]() )
).
Here's some outputs of the Future's state:
(lldb) po existingComputation
Async<Result<Array<ContentItemVM>, Never>>(Optional(Swift.Result<Swift.Array<Happ_Mobile.ContentItemVM>, Swift.Never>.success([])))
(lldb) po existingComputation.isCompleted
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x0).
(lldb) po existingComputation.result
▿ Optional<Result<Array<ContentItemVM>, Never>>
▿ some : Result<Array<ContentItemVM>, Never>
- success : 0 elements
Seems pretty wild given the implementation of AsyncType::isCompleted
seems to be simply:
public extension AsyncType {
var isCompleted: Bool {
return result != nil
}
...
}
Hi @Thomvis @adjustnox did you guys have a chance to look into this by any chance?
This is preventing us from upgrading to Xcode 11 / Swift 5 / iOS 13.
Any insight would be much appreciated
It was a hold up for us as well, so we ended up replacing the promises with escaping closures :/
Can't offer any help, I'm afraid.
Sorry that this is still an issue. Still not sure what the root cause could be and why this is not reproducible in a new/simple project.
Can you think of any way in which your projects are similarly special? E.g. what is the install method (CocoaPods, Carthage, etc.)
Cocoapods for us.
I can say we had several nested promises, which we switched to futures as per earlier suggestions.