SimplyCoreAudio
SimplyCoreAudio copied to clipboard
possible Race conditions
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.

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
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 []
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)
I'll look into this.