Assertion in AudioPlayHead::TimeSignature

Hi, I faced a crashes in AudioPlayHead::TimeSignature instance, when app/plugin is compiled with -Wp,-D_GLIBCXX_ASSERTIONS flag which is default in Fedora Linux. The purpose of this flag is “Enable lightweight assertions in the C++ standard library, such as bounds checking for the subscription operator on vectors.”

For example in BespokeSynth as the host, when any plugin is added:

/usr/include/c++/13/optional:479: constexpr _Tp& std::_Optional_base_impl<_Tp, _Dp>::_M_get() [with _Tp = juce::AudioPlayHead::TimeSignature; _Dp = std::_Optional_base<juce::AudioPlayHead::TimeSignature, true, true>]: Assertion 'this->_M_is_engaged()' failed.

#0  0x00007ffff70949ec in __pthread_kill_implementation () from /lib64/libc.so.6
#1  0x00007ffff7041176 in raise () from /lib64/libc.so.6
#2  0x00007ffff7028917 in abort () from /lib64/libc.so.6
#3  0x00007ffff74df520 in std::__glibcxx_assert_fail(char const*, int, char const*, char const*) () from /lib64/libstdc++.so.6
#4  0x0000000000c88169 in std::_Optional_base_impl<juce::AudioPlayHead::TimeSignature, std::_Optional_base<juce::AudioPlayHead::TimeSignature, true, true> >::_M_get (this=0x7fffeddff404)
    at /usr/include/c++/13/optional:479
#5  0x0000000000c87d3e in std::optional<juce::AudioPlayHead::TimeSignature>::operator-> (this=0x7fffeddff404) at /usr/include/c++/13/optional:968
#6  0x0000000000c8795c in juce::Optional<juce::AudioPlayHead::TimeSignature>::operator-> (this=0x7fffeddff404) at /usr/include/JUCE-7.0.9/modules/juce_core/containers/juce_Optional.h:126
#7  0x0000000000c86d56 in VSTPlayhead::getPosition (this=0x3085ed8) at /home/kv/src/PFM/BespokeSynth/Source/VSTPlayhead.cpp:37
#8  0x0000000000fa1c2d in juce::VSTPluginInstance::processAudio<float> (this=0xa0a5ba0, buffer=..., midiMessages=..., tmpBuffer=..., channelBuffer=..., processBlockBypassedCalled=false)
    at /usr/include/JUCE-7.0.9/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:2345
#9  0x0000000000f5b6b1 in juce::VSTPluginInstance::processBlock (this=0xa0a5ba0, buffer=..., midiMessages=...)
    at /usr/include/JUCE-7.0.9/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp:1439
#10 0x0000000000c8ffb1 in VSTPlugin::Process (this=0x30856c0, time=13539.666666665824) at /home/kv/src/PFM/BespokeSynth/Source/VSTPlugin.cpp:777
#11 0x00000000006ca570 in ModularSynth::AudioOut (this=0x2271b08, output=0x7fffe9660880, bufferSize=128, nChannels=2) at /home/kv/src/PFM/BespokeSynth/Source/ModularSynth.cpp:2023
#12 0x00000000006839d1 in MainContentComponent::audioDeviceIOCallbackWithContext (this=0x22715c0, inputChannelData=0x0, numInputChannels=0, outputChannelData=0x7fffe9660880, 
    numOutputChannels=2, numSamples=128, context=...) at /home/kv/src/PFM/BespokeSynth/Source/MainComponent.cpp:172
#13 0x0000000000e02e37 in juce::AudioDeviceManager::audioDeviceIOCallbackInt (this=0x2271780, inputChannelData=0x0, numInputChannels=0, outputChannelData=0x7fffe9660880, 
    numOutputChannels=2, numSamples=128, context=...) at /usr/include/JUCE-7.0.9/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp:1010
#14 0x0000000000e11dea in juce::AudioDeviceManager::CallbackHandler::audioDeviceIOCallbackWithContext (this=0x2270010, ins=0x0, numIns=0, outs=0x7fffe9660880, numOuts=2, numSamples=128, 
    context=...) at /usr/include/JUCE-7.0.9/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp:79
#15 0x0000000000df82cc in juce::(anonymous namespace)::ALSAThread::run (this=0x7fffe95f2d40) at /usr/include/JUCE-7.0.9/modules/juce_audio_devices/native/juce_ALSA_linux.cpp:714
#16 0x0000000000d5dff3 in juce::Thread::threadEntryPoint (this=0x7fffe95f2d40) at /usr/include/JUCE-7.0.9/modules/juce_core/threads/juce_Thread.cpp:98
#17 0x0000000000d5e0cd in juce::juce_threadEntryPoint (userData=0x7fffe95f2d40) at /usr/include/JUCE-7.0.9/modules/juce_core/threads/juce_Thread.cpp:120
#18 0x0000000000d8479e in operator() (__closure=0x0, userData=0x7fffe95f2d40) at /usr/include/JUCE-7.0.9/modules/juce_core/native/juce_Threads_linux.cpp:40
#19 0x0000000000d847c2 in _FUN () at /usr/include/JUCE-7.0.9/modules/juce_core/native/juce_Threads_linux.cpp:43
#20 0x00007ffff7092bb2 in start_thread () from /lib64/libc.so.6
#21 0x00007ffff711400c in clone3 () from /lib64/libc.so.6

Just … imho, enabling GLIBCXX_ASSERTIONS adds overhead that plugin developers, seeking maximum performance, would probably prefer to avoid, which is why I’d suggest you just build your plugins without it enabled.

Based on the stack trace, this looks like a bug in BespokeSynth. VSTPlayhead is a custom type that implements getPosition. I’d recommend looking at the implementation of this function to see whether it’s accessing a disengaged Optional instance.

@anon48770766 yes, I disabled this for Fedora builds
@reuk as there is the same crash for Vaporizer2 I thought it’s in JUCE somewhere. I’ll try to find where it goes wrong in the Bespoke’s code.