Skip to content
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

ThreadSanitizer Issue - Swift access race in ImageDownloader.clean #763

Closed
3 tasks done
AndrewBarba opened this issue Sep 5, 2017 · 6 comments
Closed
3 tasks done
Assignees

Comments

@AndrewBarba
Copy link

AndrewBarba commented Sep 5, 2017

Check List

Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.

Issue Description

What

screen shot 2017-09-04 at 9 04 57 pm

==================
WARNING: ThreadSanitizer: Swift access race (pid=46324)
  Modifying access at 0x7b240002c420 by thread T1:
  * #0 _T010Kingfisher15ImageDownloaderC5cleany10Foundation3URLV3for_tFyycfU_ ImageDownloader.swift:382 (Kingfisher:x86_64+0x515eb)
    #1 _T010Kingfisher15ImageDownloaderC5cleany10Foundation3URLV3for_tFyycfU_TA ImageDownloader.swift (Kingfisher:x86_64+0x58c58)
    #2 _T0s5Error_pIxzo_ytsAA_pIxrzo_TR ImageDownloader.swift (Kingfisher:x86_64+0x4b366)
    #3 _T0s5Error_pIxzo_ytsAA_pIxrzo_TRTA.66 ImageDownloader.swift (Kingfisher:x86_64+0x58d2f)
    #4 _T0So13DispatchQueueC0A0E11_syncHelper33_F417D752D2C4E9330E1C700411CE0C6ALLxyAC0A8WorkItemCc2fn_AC0anO5FlagsV5flagsxyKc7executexs5Error_pKc6rescuetKlFyycfU_Tf4ngn_n <null>:1059424 (libswiftDispatch.dylib:x86_64+0x13b9b)
    #5 _dispatch_client_callout <null>:1059424 (libdispatch.dylib:x86_64+0x343b)
    #6 _T0So13DispatchQueueC0A0E12_syncBarrier33_F417D752D2C4E9330E1C700411CE0C6ALLyyyc5block_tFTA <null>:1059424 (libswiftDispatch.dylib:x86_64+0x1390c)
    #7 _T010Kingfisher29ImageDownloaderSessionHandlerC14cleanFetchLoad33_1CBBE1CEF600480D48F123F40F117AB5LLy10Foundation3URLV3for_tF ImageDownloader.swift:470 (Kingfisher:x86_64+0x545a4)
    #8 _T010Kingfisher29ImageDownloaderSessionHandlerC07processB033_1CBBE1CEF600480D48F123F40F117AB5LLySo14URLSessionTaskC3for_10Foundation3URLV3urltFyycfU_ ImageDownloader.swift:510 (Kingfisher:x86_64+0x55f5d)
    #9 _T010Kingfisher29ImageDownloaderSessionHandlerC07processB033_1CBBE1CEF600480D48F123F40F117AB5LLySo14URLSessionTaskC3for_10Foundation3URLV3urltFyycfU_TA ImageDownloader.swift (Kingfisher:x86_64+0x5afa0)
    #10 _T0Ix_IyB_TR AnimatedImageView.swift (Kingfisher:x86_64+0xaeec)
    #11 __tsan::invoke_and_release_block(void*) <null>:1059424 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x637fb)
    #12 _dispatch_client_callout <null>:1059424 (libdispatch.dylib:x86_64+0x343b)

  Previous read of size 8 at 0x7b240002c420 by thread T6:
  * #0 _T010Kingfisher15ImageDownloaderC10fetchLoadss10DictionaryVy10Foundation3URLVAC0B9FetchLoadCGfg ImageDownloader.swift (Kingfisher:x86_64+0x491d3)
    #1 _T010Kingfisher29ImageDownloaderSessionHandlerC14cleanFetchLoad33_1CBBE1CEF600480D48F123F40F117AB5LLy10Foundation3URLV3for_tF ImageDownloader.swift:472 (Kingfisher:x86_64+0x545dd)
    #2 _T010Kingfisher29ImageDownloaderSessionHandlerC07processB033_1CBBE1CEF600480D48F123F40F117AB5LLySo14URLSessionTaskC3for_10Foundation3URLV3urltFyycfU_ ImageDownloader.swift:510 (Kingfisher:x86_64+0x55f5d)
    #3 _T010Kingfisher29ImageDownloaderSessionHandlerC07processB033_1CBBE1CEF600480D48F123F40F117AB5LLySo14URLSessionTaskC3for_10Foundation3URLV3urltFyycfU_TA ImageDownloader.swift (Kingfisher:x86_64+0x5afa0)
    #4 _T0Ix_IyB_TR AnimatedImageView.swift (Kingfisher:x86_64+0xaeec)
    #5 __tsan::invoke_and_release_block(void*) <null>:1059424 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x637fb)
    #6 _dispatch_client_callout <null>:1059424 (libdispatch.dylib:x86_64+0x343b)

  Issue is caused by frames marked with "*".

  Location is heap block of size 136 at 0x7b240002c3a0 allocated by main thread:
    #0 malloc <null>:1059440 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x46a2a)
    #1 swift_slowAlloc <null>:1059440 (libswiftCore.dylib:x86_64+0x342c08)
    #2 _T010Kingfisher15ImageDownloaderCACSS4name_tcfC ImageDownloader.swift (Kingfisher:x86_64+0x4946c)
    #3 globalinit_33_1CBBE1CEF600480D48F123F40F117AB5_func1 ImageDownloader.swift:231 (Kingfisher:x86_64+0x493e6)
    #4 dispatch_once <null>:1059440 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x64464)
    #5 dispatch_once_f <null>:1059440 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x64556)
    #6 _T010Kingfisher15ImageDownloaderC7defaultACfau ImageDownloader.swift:231 (Kingfisher:x86_64+0x494e9)
    #7 _T010Kingfisher0A7ManagerCACycfc KingfisherManager.swift:91 (Kingfisher:x86_64+0x8efac)
    #8 _T010Kingfisher0A7ManagerCACycfC KingfisherManager.swift (Kingfisher:x86_64+0x8e647)
    #9 globalinit_33_34361C00AC0F1B424C7ED272C635AF94_func2 KingfisherManager.swift:69 (Kingfisher:x86_64+0x8e59f)
    #10 dispatch_once <null>:1059440 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x64464)
    #11 dispatch_once_f <null>:1059440 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x64556)
    #12 _T010Kingfisher0A7ManagerC6sharedACfau KingfisherManager.swift:69 (Kingfisher:x86_64+0x8e6b9)
    #13 _T010KingfisherAACAASo11UIImageViewCRbzlE8setImageAA08RetrieveE4TaskCAA8Resource_pSg4with_So0B0CSg11placeholderSayAA0A15OptionsInfoItemOGSg7optionsys5Int64V_AUtcSg13progressBlockyAM_So7NSErrorCSgAA9CacheTypeO10Foundation3URLVSgtcSg17completionHandlertF ImageView+Kingfisher.swift:70 (Kingfisher:x86_64+0x7d785)
    #14 _T08Barstool18StoryTableViewCellC6layouty0A4Core0B0C5story_tF StoryTableViewCell.swift:79 (Barstool:x86_64+0x10000991b)
    #15 _T08Barstool18StoryTableViewCellC5story0A4Core0B0CSgfW StoryTableViewCell.swift:70 (Barstool:x86_64+0x10000849e)
    #16 _T08Barstool18StoryTableViewCellC5story0A4Core0B0CSgfs StoryTableViewCell.swift (Barstool:x86_64+0x100008713)
    #17 _T08Barstool32CommonStoriesTableViewControllerC05tableE0So07UITableE4CellCSo0hE0C_10Foundation9IndexPathV12cellForRowAttF CommonStoriesTableViewController.swift:45 (Barstool:x86_64+0x100040531)
    #18 _T08Barstool32CommonStoriesTableViewControllerC05tableE0So07UITableE4CellCSo0hE0C_10Foundation9IndexPathV12cellForRowAttFTo CommonStoriesTableViewController.swift (Barstool:x86_64+0x100040755)
    #19 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] <null>:1059440 (UIKit:x86_64+0x181f93)
    #20 start <null>:1059440 (libdyld.dylib:x86_64+0xd80)

  Thread T1 (tid=1273014, running) is a GCD worker thread

  Thread T6 (tid=1273034, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: Swift access race ImageDownloader.swift:382 in _T010Kingfisher15ImageDownloaderC5cleany10Foundation3URLV3for_tFyycfU_
==================

Reproduce

Not sure, I just have a standard table view where each cell has 2 image views being populated by Kf. I have the ThreadSanitizer options turned on in my dev scheme

@onevcat
Copy link
Owner

onevcat commented Sep 5, 2017

Thanks for reporting this. I will take a look at it later.

@onevcat onevcat self-assigned this Sep 5, 2017
@AndrewBarba
Copy link
Author

AndrewBarba commented Sep 5, 2017

No problem, I should have also stated this is on Swift 4 (swift4 branch) and iOS 11, Xcode 9 beta 6.

@shilei365
Copy link

shilei365 commented Oct 9, 2017

I have the same problem, but only on simulator - Swift 3.2 and Xcode 9

@onevcat
Copy link
Owner

onevcat commented Oct 9, 2017

After some investigation, I guess it might be an issue of the ThreadSanitizer of Xcode, which might not be able to work well with a barrier queue. Like indicated in the documentation of dispatch_barrier_sync:

When the barrier block reaches the front of a private concurrent queue, it is not executed immediately. Instead, the queue waits until its currently executing blocks finish executing. At that point, the queue executes the barrier block by itself. Any blocks submitted after the barrier block are not executed until the barrier block completes.

Both of the racing statement are surrounded by a barrier sync, it should be totally fine since the execution of them will be happened in a sequence way, without a race condition. There should be no case that both of them get accessed or modified.

So you could just ignore this. I don't think the sanitizer works well on this. However, I am not 100% sure about for which case the thread sanitizer could give a warning (since it is true that they happens in different threads. So maybe it is just the way thread sanitizer works).

Maybe I was wrong. Please let me know if you have any other ideas. Thanks!

@onevcat onevcat closed this as completed Oct 9, 2017
@shilei365
Copy link

If unchecking the option "Thread sanitizer" in the xcode settings, then it works well :)

@onevcat
Copy link
Owner

onevcat commented Oct 16, 2017

Umm, it seems that I misunderstood the sanitizer warning. There was actually a race condition in reading without barrier. Now it should be fixed in #790

@AndrewBarba @shilei365 Thanks for reporting this!

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

No branches or pull requests

3 participants