Skip to content

audiounit_ios: add @autoreleasepool to GetLatency

GetLatency calls [AVAudioSession outputLatency] in the following callstack:

  • _malloc_zone_malloc_instrumented_or_legacy
  • _Block_copy
  • -[_NSXPCDistantObject _initWithConnection:proxyNumber:generationCount:interface:options:error:]
  • -[NSXPCConnection synchronousRemoteObjectProxyWithErrorHandler:]
  • caulk::xpc::message<id __strong, objc_object* __strong, unsigned int>::sync_proxy()
  • GetPropertyXPC(std::__1::shared_ptras::client::XPCConnection, unsigned int, NSString*, bool)
  • GetProperty(AVAudioSessionImpl*, NSString*, bool)
  • float GetProperty_DefaultToZeroXPC(AVAudioSessionImpl*, NSString*, bool)
  • -[AVAudioSession outputLatency]
  • GetLatency
  • GetLatency
  • ca_Render
  • RenderCallback
  • ausdk::AUInputElement::PullInput(unsigned int&, AudioTimeStamp const&, unsigned int, unsigned int)
  • AUInputFormatConverter2::InputProc(OpaqueAudioConverter*, unsigned int*, AudioBufferList*, AudioStreamPacketDescription**, void*)
  • caulk::expected<unsigned int, int> caulk::function_ref<caulk::expected<unsigned int, int> (ACAudioSpan&)>::functor_invoker<acv2::AudioConverterV2::fillComplexBuffer(int ()(OpaqueAudioConverter, unsigned int*, AudioBufferList*, AudioStreamPacketDescription**, void*), void*, unsigned int*, AudioBufferList*, AudioStreamPacketDescription*, AudioStreamPacketDependencyInfo*)::$_2>(caulk::details::erased_callable<caulk::expected<unsigned int, int> (ACAudioSpan&)> const&, ACAudioSpan&)
  • acv2::AudioConverterChain::ObtainInput(acv2::AudioConverterBase&, unsigned int)
  • acv2::CBRConverter::ProduceOutput(ACAudioSpan&)
  • acv2::AudioConverterChain::ProduceOutput(caulk::function_ref<caulk::expected<unsigned int, int> (ACAudioSpan&)>, ACBaseAudioSpan&)
  • acv2::AudioConverterV2::fillComplexBuffer(int ()(OpaqueAudioConverter, unsigned int*, AudioBufferList*, AudioStreamPacketDescription**, void*), void*, unsigned int*, AudioBufferList*, AudioStreamPacketDescription*, AudioStreamPacketDependencyInfo*)
  • with_resolved(OpaqueAudioConverter*, caulk::function_ref<int (AudioConverterAPI*)>)
  • AudioConverterFillComplexBuffer
  • AUConverterBase::RenderBus(unsigned int&, AudioTimeStamp const&, unsigned int, unsigned int)
  • AURemoteIO::RenderBus(unsigned int&, AudioTimeStamp const&, unsigned int, unsigned int)
  • ausdk::AUBase::DoRender(unsigned int&, AudioTimeStamp const&, unsigned int, unsigned int, AudioBufferList&)
  • AURemoteIO::PerformIO(unsigned int, unsigned int, unsigned int, AudioTimeStamp const&, AudioTimeStamp const&, AudioBufferList const*, AudioBufferList*, int&)
  • _XPerformIO
  • mshMIGPerform
  • MSHMIGDispatchMessage
  • void* caulk::thread_proxy<std::__1::tuple<caulk::thread::attributes, AURemoteIO::IOThread::IOThread(AURemoteIO&, caulk::thread::attributes const&, caulk::mach::os_workgroup_managed const&)::'lambda'(), std::__1::tuple<>>>(void*)
  • _pthread_start
  • thread_start

The call to Objective-C function might generate objects released from autoreleasepool, which seems to be the case with the call to [NSXPConnection synchronousRemoteObjectProxyWithErrorHandler]1.

I've not found where exactly [[block copy] autorelease] was called but setting up the autoreleasepool before unwinding back to the C code removes the accumulatoin of memory on this specify callstack.

  1. https://developer.apple.com/documentation/foundation/nsxpcconnection/2879410-synchronousremoteobjectproxywith?language=objc

Merge request reports