SimplyCoreAudio icon indicating copy to clipboard operation
SimplyCoreAudio copied to clipboard

possible Race conditions

Open ryanfrancesconi opened this issue 4 years ago • 3 comments

Probably just wrapping that variable in a lock would fix it. I'm not actually sure how to replicate this, but lately i've been running with the sanitizer on and saw it.

image

WARNING: ThreadSanitizer: Swift access race (pid=29340)
  Read of size 8 at 0x00010a246610 by thread T30:
    #0 closure #1 in propertyListener(objectID:numInAddresses:inAddresses:clientData:) <null>:107410496 (ADD:arm64+0x101844ccc)
    #1 partial apply for closure #1 in propertyListener(objectID:numInAddresses:inAddresses:clientData:) <null>:107410496 (ADD:arm64+0x101845d98)
    #2 thunk for @callee_guaranteed (@guaranteed AudioDevice) -> (@unowned Bool, @error @owned Error) <null>:107410496 (ADD:arm64+0x101842cf4)
    #3 thunk for @callee_guaranteed (@guaranteed AudioDevice) -> (@unowned Bool, @error @owned Error)partial apply <null>:107410496 (ADD:arm64+0x101845e0c)
    #4 _ArrayProtocol.filter(_:) <null>:107410496 (libswiftCore.dylib:arm64e+0x34b88)
    #5 @objc propertyListener(objectID:numInAddresses:inAddresses:clientData:) <null>:107410496 (ADD:arm64+0x101843ae4)
    #6 HALObject::PropertiesChanged(unsigned int, AudioObjectPropertyAddress const*) <null>:107410496 (CoreAudio:arm64e+0x1f1078)
    #7 _dispatch_client_callout <null>:107410496 (libdispatch.dylib:arm64e+0x5dc8)

  Previous modifying access of Swift variable at 0x00010a246610 by thread T3:
    #0 AudioHardware.add(device:) <null>:107410496 (ADD:arm64+0x101841f40)
    #1 propertyListener(objectID:numInAddresses:inAddresses:clientData:) <null>:107410496 (ADD:arm64+0x1018442e4)
    #2 @objc propertyListener(objectID:numInAddresses:inAddresses:clientData:) <null>:107410496 (ADD:arm64+0x101843ae4)
    #3 HALObject::PropertiesChanged(unsigned int, AudioObjectPropertyAddress const*) <null>:107410496 (CoreAudio:arm64e+0x1f1078)
    #4 _dispatch_client_callout <null>:107410496 (libdispatch.dylib:arm64e+0x5dc8)

  Location is heap block of size 25 at 0x00010a246600 allocated by main thread:
    #0 __sanitizer_mz_malloc <null>:107410496 (libclang_rt.tsan_osx_dynamic.dylib:arm64+0x510c8)
    #1 _malloc_zone_malloc <null>:107410496 (libsystem_malloc.dylib:arm64e+0x1d530)
    #2 SimplyCoreAudio.init() <null>:107410496 (ADD:arm64+0x101876028)
    #3 SimplyCoreAudio.__allocating_init() <null>:107410496 (ADD:arm64+0x101875ea4)
    #4 AudioEngineManager.init() AudioEngineManager.swift:8 (ADD:arm64+0x100cbddb8)
    #5 AudioEngineManager.__allocating_init() AudioEngineManager.swift (ADD:arm64+0x100cbdd30)
    #6 ADDApplication.init(nibName:bundle:) ADDApplication.swift:90 (ADD:arm64+0x1011d29d0)
    #7 @objc ADDApplication.init(nibName:bundle:) <compiler-generated> (ADD:arm64+0x1011d35f4)
    #8 ADDApplication.init() ADDApplication.swift:137 (ADD:arm64+0x1011d159c)
    #9 @objc ADDApplication.init() <compiler-generated> (ADD:arm64+0x1011d1638)
    #10 ADDApplication.__allocating_init() ADDApplication.swift (ADD:arm64+0x1011d1458)
    #11 ADDWindowController.init(window:) ADDWindowController.swift:11 (ADD:arm64+0x100514498)
    #12 @objc ADDWindowController.init(window:) <compiler-generated> (ADD:arm64+0x1005146f0)
    #13 -[NSWindowController initWithWindowNibName:owner:] <null>:107410496 (AppKit:arm64e+0x15dec8)
    #14 @objc ADDWindowController.init() <compiler-generated> (ADD:arm64+0x1005130cc)
    #15 -[NSClassSwapper initWithCoder:] <null>:107410496 (AppKit:arm64e+0xa0860)
    #16 start <null>:107410496 (libdyld.dylib:arm64e+0x1844c)

  Thread T30 (tid=718856, running) created by thread T29 at:
    #0 pthread_create <null>:107410496 (libclang_rt.tsan_osx_dynamic.dylib:arm64+0x28430)
    #1 _dispatch_root_queue_poke_slow <null>:107410496 (libdispatch.dylib:arm64e+0x16f54)
    #2 HALC_ProxyIOContext::EnqueuePauseIO(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool) <null>:107410496 (CoreAudio:arm64e+0x173434)
    #3 _dispatch_client_callout <null>:107410496 (libdispatch.dylib:arm64e+0x5dc8)

  Thread T3 (tid=718191, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: Swift access race (ADD:arm64+0x101844ccc) in closure #1 in propertyListener(objectID:numInAddresses:inAddresses:clientData:)+0xa4

ryanfrancesconi avatar Aug 12 '21 15:08 ryanfrancesconi

I've noticed that Blackhole was removed and re-added behind the scenes and that's what caused the event. Not sure why yet.

looks like its ID changed for some reason:

addHardwareObservers():566:addedDevices [] removedDevices [BlackHole 16ch (87)]
...
2021-08-12 11:28:29.871265-0700 ADD[29340:718856]  AudioObjectHasProperty: no object with given ID 87
2021-08-12 11:28:29.931903-0700 ADD[29340:718856] Unable to add property listener for BlackHole 16ch (99).
2021-08-12 11:28:29.933807-0700 ADD[29340:717685] [Debug] ADD+Engine.swift:addHardwareObservers():566:addedDevices [BlackHole 16ch (99)] removedDevices []

ryanfrancesconi avatar Aug 12 '21 18:08 ryanfrancesconi

Here's another which appears to just be from generating the queueLabel:

WARNING: ThreadSanitizer: data race (pid=52285)
  Read of size 8 at 0x00010797d658 by thread T3:
    #0 AudioObjectPool.queueLabel.getter <null>:62321728 (ADD:arm64+0x1018631ac)
    #1 AudioObjectPool.queue.getter <null>:62321728 (ADD:arm64+0x1018636dc)
    #2 AudioObjectPool.get<A>(_:) <null>:62321728 (ADD:arm64+0x101863f40)
    #3 static AudioDevice.lookup(by:) <null>:62321728 (ADD:arm64+0x10187de90)
    #4 closure #1 in AudioHardware.allDevices.getter <null>:62321728 (ADD:arm64+0x10185f53c)
    #5 thunk for @callee_guaranteed (@unowned UInt32) -> (@owned AudioDevice?, @error @owned Error) <null>:62321728 (ADD:arm64+0x10185f5bc)
    #6 partial apply for thunk for @callee_guaranteed (@unowned UInt32) -> (@owned AudioDevice?, @error @owned Error) <null>:62321728 (ADD:arm64+0x101861dac)
    #7 Sequence.compactMap<A>(_:) <null>:62321728 (libswiftCore.dylib:arm64e+0x1afb64)
    #8 propertyListener(objectID:numInAddresses:inAddresses:clientData:) <null>:62321728 (ADD:arm64+0x101860a54)
    #9 @objc propertyListener(objectID:numInAddresses:inAddresses:clientData:) <null>:62321728 (ADD:arm64+0x10186062c)
    #10 HALObject::PropertiesChanged(unsigned int, AudioObjectPropertyAddress const*) <null>:62321728 (CoreAudio:arm64e+0x1f1078)
    #11 _dispatch_client_callout <null>:62321728 (libdispatch.dylib:arm64e+0x5dc8)

  Previous write of size 8 at 0x00010797d658 by thread T6:
    #0 AudioObjectPool.queueLabel.getter <null>:62321728 (ADD:arm64+0x1018631d8)
    #1 AudioObjectPool.queue.getter <null>:62321728 (ADD:arm64+0x1018636dc)
    #2 AudioObjectPool.get<A>(_:) <null>:62321728 (ADD:arm64+0x101863f40)
    #3 static AudioDevice.lookup(by:) <null>:62321728 (ADD:arm64+0x10187de90)
    #4 closure #1 in AudioHardware.allDevices.getter <null>:62321728 (ADD:arm64+0x10185f53c)
    #5 thunk for @callee_guaranteed (@unowned UInt32) -> (@owned AudioDevice?, @error @owned Error) <null>:62321728 (ADD:arm64+0x10185f5bc)
    #6 partial apply for thunk for @callee_guaranteed (@unowned UInt32) -> (@owned AudioDevice?, @error @owned Error) <null>:62321728 (ADD:arm64+0x101861dac)
    #7 Sequence.compactMap<A>(_:) <null>:62321728 (libswiftCore.dylib:arm64e+0x1afb64)
    #8 propertyListener(objectID:numInAddresses:inAddresses:clientData:) <null>:62321728 (ADD:arm64+0x101860a54)
    #9 @objc propertyListener(objectID:numInAddresses:inAddresses:clientData:) <null>:62321728 (ADD:arm64+0x10186062c)
    #10 HALObject::PropertiesChanged(unsigned int, AudioObjectPropertyAddress const*) <null>:62321728 (CoreAudio:arm64e+0x1f1078)
    #11 _dispatch_client_callout <null>:62321728 (libdispatch.dylib:arm64e+0x5dc8)


ryanfrancesconi avatar Aug 13 '21 15:08 ryanfrancesconi

I'll look into this.

ryanfrancesconi avatar Aug 25 '21 15:08 ryanfrancesconi