@juce_team, one thing that did come up whilst I was trying to add this to my existing dogfood tests running the juce plugins is that they can do a fair bit of allocating. I just wanted to get your stance on if there’s any chance these might be tightened up or if you just consider them “demos” and I should remove them from my tests?
Here’s an example:
Real-time violation: intercepted call to real-time unsafe function realloc in real-time context! Stack trace:
0 librtcheck.dylib 0x0000000108292f5c _ZN3rtc14get_stacktraceEv + 80
1 librtcheck.dylib 0x0000000108292bdc _ZN3rtc32log_function_if_realtime_contextEPKc + 300
2 librtcheck.dylib 0x00000001082935b4 _Z44log_function_if_realtime_context_and_enabledN3rtc11check_flagsEPKc + 64
3 librtcheck.dylib 0x0000000108293658 wrap_realloc + 36
4 DSPModulePluginDemo 0x0000000123719ddc _ZZN4juce9HeapBlockIPNS_14MessageManager11MessageBaseELb0EE14reallocWrapperEPvmENKUlvE_clEv + 32
5 DSPModulePluginDemo 0x0000000123719d94 _ZN4juce9HeapBlockIPNS_14MessageManager11MessageBaseELb0EE7wrapperIZNS4_14reallocWrapperEPvmEUlvE_EEPS3_mOT_ + 56
6 DSPModulePluginDemo 0x0000000123719d50 _ZN4juce9HeapBlockIPNS_14MessageManager11MessageBaseELb0EE14reallocWrapperEPvm + 48
7 DSPModulePluginDemo 0x0000000123719d0c _ZN4juce9HeapBlockIPNS_14MessageManager11MessageBaseELb0EE7reallocImEEvT_m + 52
8 DSPModulePluginDemo 0x0000000123719c90 _ZN4juce9ArrayBaseIPNS_14MessageManager11MessageBaseENS_15CriticalSectionEE24setAllocatedSizeInternalEi + 40
9 DSPModulePluginDemo 0x0000000123719c38 _ZN4juce9ArrayBaseIPNS_14MessageManager11MessageBaseENS_15CriticalSectionEE16setAllocatedSizeEi + 176
10 DSPModulePluginDemo 0x000000012371a48c _ZN4juce9ArrayBaseIPNS_14MessageManager11MessageBaseENS_15CriticalSectionEE19ensureAllocatedSizeEi + 88
11 DSPModulePluginDemo 0x000000012371a378 _ZN4juce9ArrayBaseIPNS_14MessageManager11MessageBaseENS_15CriticalSectionEE7addImplIJRKS3_EEEvDpOT_ + 52
12 DSPModulePluginDemo 0x000000012371a338 _ZN4juce9ArrayBaseIPNS_14MessageManager11MessageBaseENS_15CriticalSectionEE3addERKS3_ + 32
13 DSPModulePluginDemo 0x000000012371a2b4 _ZN4juce21ReferenceCountedArrayINS_14MessageManager11MessageBaseENS_15CriticalSectionEE3addEPS2_ + 64
14 DSPModulePluginDemo 0x00000001236fc31c _ZN4juce12MessageQueue4postEPNS_14MessageManager11MessageBaseE + 36
15 DSPModulePluginDemo 0x00000001236f217c _ZN4juce14MessageManager24postMessageToSystemQueueEPNS0_11MessageBaseE + 120
16 DSPModulePluginDemo 0x00000001236f1c00 _ZN4juce14MessageManager11MessageBase4postEv + 92
17 DSPModulePluginDemo 0x00000001236f44fc _ZN4juce12AsyncUpdater18triggerAsyncUpdateEv + 156
18 DSPModulePluginDemo 0x0000000122d59924 _ZN4juce18ComponentRestarter7restartEi + 116
19 DSPModulePluginDemo 0x0000000122d5526c _ZN4juce22JuceVST3EditController21audioProcessorChangedEPNS_14AudioProcessorERKNS_22AudioProcessorListener13ChangeDetailsE + 776
20 DSPModulePluginDemo 0x00000001238445d4 _ZN4juce14AudioProcessor17updateHostDisplayERKNS_22AudioProcessorListener13ChangeDetailsE + 132
21 DSPModulePluginDemo 0x0000000123844540 _ZN4juce14AudioProcessor17setLatencySamplesEi + 116
22 DSPModulePluginDemo 0x0000000122db1b10 _ZN19DspModulePluginDemo12processBlockERN4juce11AudioBufferIfEERNS0_10MidiBufferE + 356
23 DSPModulePluginDemo 0x0000000122d5e5c4 _ZN4juce17JuceVST3Component12processAudioIfEEvRN9Steinberg3Vst11ProcessDataE + 532
24 DSPModulePluginDemo 0x0000000122d2b2b4 _ZN4juce17JuceVST3Component7processERN9Steinberg3Vst11ProcessDataE + 864
25 pluginval 0x0000000105293d9c _ZN4juce26VST3PluginInstanceHeadless12processAudioIfEEvRNS_11AudioBufferIT_EERNS_10MidiBufferEN9Steinberg3Vst19SymbolicSampleSizesEb + 480
26 pluginval 0x000000010526ebf4 _ZN4juce26VST3PluginInstanceHeadless12processBlockERNS_11AudioBufferIfEERNS_10MidiBufferE + 192
27 pluginval 0x0000000104f7c940 _ZN14AutomationTest7runTestER11PluginTestsRN4juce19AudioPluginInstanceE + 2028
28 pluginval 0x0000000104f6caa0 _ZN11PluginTests8testTypeERKN4juce17PluginDescriptionE + 2188
29 pluginval 0x0000000104f6c070 _ZN11PluginTests7runTestEv + 1328
30 pluginval 0x000000010513e040 _ZN4juce8UnitTest11performTestEPNS_14UnitTestRunnerE + 148
31 pluginval 0x000000010513ed44 _ZN4juce14UnitTestRunner8runTestsERKNS_5ArrayIPNS_8UnitTestENS_20DummyCriticalSectionELi0EEEx + 424
32 pluginval 0x0000000104f96c00 _Z8runTestsR11PluginTestsNSt3__18functionIFvRKN4juce6StringEEEE + 228
33 pluginval 0x0000000104f95f48 _Z8validateRKN4juce6StringEN11PluginTests7OptionsENSt3__18functionIFvS2_EEE + 156
34 pluginval 0x0000000104f95c0c _ZN14AsyncValidator3runEv + 156
35 pluginval 0x0000000104f95b64 _ZZN14AsyncValidatorC1ERKN4juce6StringEN11PluginTests7OptionsENSt3__18functionIFvS1_EEENS7_IFvS1_jEEENS7_IFvS3_EEEENKUlvE_clEv + 28
36 pluginval 0x0000000104f95b14 _ZNSt3__18__invokeB8ne180100IZN14AsyncValidatorC1ERKN4juce6StringEN11PluginTests7OptionsENS_8functionIFvS3_EEENS8_IFvS3_jEEENS8_IFvS5_EEEEUlvE_JEEEDTclclsr3stdE7declvalIT_EEspclsr3stdE7declvalIT0_EEEEOSG_DpOSH_ + 24
37 pluginval 0x0000000104f95af0 _ZNSt3__116__thread_executeB8ne180100INS_10unique_ptrINS_15__thread_structENS_14default_deleteIS2_EEEEZN14AsyncValidatorC1ERKN4juce6StringEN11PluginTests7OptionsENS_8functionIFvS8_EEENSD_IFvS8_jEEENSD_IFvSA_EEEEUlvE_JEJEEEvRNS_5tupleIJT_T0_DpT1_EEENS_15__tuple_indicesIJXspT2_EEEE + 28
38 pluginval 0x0000000104f95800 _ZNSt3__114__thread_proxyB8ne180100INS_5tupleIJNS_10unique_ptrINS_15__thread_structENS_14default_deleteIS3_EEEEZN14AsyncValidatorC1ERKN4juce6StringEN11PluginTests7OptionsENS_8functionIFvS9_EEENSE_IFvS9_jEEENSE_IFvSB_EEEEUlvE_EEEEEPvSN_ + 84
39 libsystem_pthread.dylib 0x0000000183bbf2e4 _pthread_start + 136
40 libsystem_pthread.dylib 0x0000000183bba0fc thread_start + 8
Here’s the relevant parts demangled:
juce::HeapBlock::realloc<…>(unsigned long, unsigned long) juce_HeapBlock.h:299
juce::ArrayBase::setAllocatedSizeInternal(int) juce_ArrayBase.h:432
juce::ArrayBase::setAllocatedSize(int) juce_ArrayBase.h:232
juce::ArrayBase::ensureAllocatedSize(int) juce_ArrayBase.h:243
juce::ArrayBase::addImpl<…>(juce::MessageManager::MessageBase *const &) juce_ArrayBase.h:561
juce::ArrayBase::add(juce::MessageManager::MessageBase *const &) juce_ArrayBase.h:273
juce::ReferenceCountedArray::add(juce::MessageManager::MessageBase *) juce_ReferenceCountedArray.h:369
juce::MessageQueue::post(juce::MessageManager::MessageBase *) juce_MessageQueue_mac.h:67
juce::MessageManager::postMessageToSystemQueue(juce::MessageManager::MessageBase *) juce_MessageManager_mac.mm:436
juce::MessageManager::MessageBase::post() juce_MessageManager.cpp:85
juce::AsyncUpdater::triggerAsyncUpdate() juce_AsyncUpdater.cpp:81
juce::ComponentRestarter::restart(int) juce_VST3Common.h:1651
juce::JuceVST3EditController::audioProcessorChanged(juce::AudioProcessor *, const juce::AudioProcessorListener::ChangeDetails &) juce_audio_plugin_client_VST3.cpp:1561
juce::AudioProcessor::updateHostDisplay(const juce::AudioProcessorListener::ChangeDetails &) juce_AudioProcessor.cpp:435
juce::AudioProcessor::setLatencySamples(int) juce_AudioProcessor.cpp:420
DspModulePluginDemo::processBlock(juce::AudioBuffer<…> &, juce::MidiBuffer &) DSPModulePluginDemo.h:194
In the DSPModulePluginDemo specifically, the fact that updates are async and can lead to allocations is highlighted:
wrap_malloc(size_t) rtcheck.cpp:287
<lambda>::operator()() const juce_HeapBlock.h:356
juce::HeapBlock::wrapper<…>(unsigned long, <lambda> &&) juce_HeapBlock.h:343
juce::HeapBlock::mallocWrapper(unsigned long) juce_HeapBlock.h:356
juce::HeapBlock::allocate<…>(unsigned long, bool) juce_HeapBlock.h:288
juce::AudioBuffer::setSize(int, int, bool, bool, bool) juce_AudioSampleBuffer.h:442
juce::dsp::DelayLine::setMaximumDelayInSamples(int) juce_DelayLine.cpp:97
juce::dsp::DelayLine::DelayLine(int) juce_DelayLine.cpp:52
juce::dsp::DelayLine::DelayLine(int) juce_DelayLine.cpp:47
juce::dsp::Chorus::prepare(const juce::dsp::ProcessSpec &) juce_Chorus.cpp:103
<lambda>::operator()<…>(auto &, auto) const juce_ProcessorChain.h:91
juce::dsp::detail::forEachInTuple<…>(auto &&, auto &&, std::integer_sequence<…>) juce_ProcessorChain.h:48
juce::dsp::detail::forEachInTuple<…>(auto &&, auto &&) juce_ProcessorChain.h:57
juce::dsp::ProcessorChain::prepare(const juce::dsp::ProcessSpec &) juce_ProcessorChain.h:91
DspModulePluginDemo::prepareToPlay(double, int) DSPModulePluginDemo.h:166
DspModulePluginDemo::update() DSPModulePluginDemo.h:833
DspModulePluginDemo::processBlock(juce::AudioBuffer<…> &, juce::MidiBuffer &) DSPModulePluginDemo.h:187
juce::JuceVST3Component::processAudio<…>(Steinberg::Vst::ProcessData &) juce_audio_plugin_client_VST3.cpp:3853
juce::JuceVST3Component::process(Steinberg::Vst::ProcessData &) juce_audio_plugin_client_VST3.cpp:3731
juce::VST3PluginInstanceHeadless::processAudio<…>(juce::AudioBuffer<…> &, juce::MidiBuffer &, Steinberg::Vst::SymbolicSampleSizes, bool) juce_VST3PluginFormatImpl.h:2500
juce::VST3PluginInstanceHeadless::processBlock(juce::AudioBuffer<…> &, juce::MidiBuffer &) juce_VST3PluginFormatImpl.h:2415
AutomationTest::runTest(PluginTests &, juce::AudioPluginInstance &) BasicTests.cpp:440
Anyway, I thought you might find those findings interesting.