ebu / ear-production-suite

The EAR Production Suite is a set of VST® plugins and tools for producing immersive and personalizable audio content suitable for any Next Generation Audio codec. It is based on the Audio Definition Model (ITU-R BS.2076) and the ITU ADM Renderer (ITU-R BS.2127) and enables monitoring on any ITU-R BS.2051 loudspeaker configuration.
https://ear-production-suite.ebu.io/
GNU General Public License v3.0
102 stars 20 forks source link

Fix #277 - Stack overflow in Bin Mon message handler #278

Closed firthm01 closed 6 months ago

firthm01 commented 6 months ago

As per #277, a crash would occur (probably only on windows) if the AdmPresetDefinitionsHandler was first instantiated as a singleton via an NNG message, due to the NNG threads having a small stack. We had previously overcome a similar issue in the LS monitoring plugins by wrapping SceneGainsCalculator::update code in a thread. I used a similar fix here, but it made sense for the thread launching to occur further up the call stack since for both the LS mons and Bin mon, the message handler call stems from MonitoringMetadataReceiver::handleReceive

LS mon call stack from message received to SceneGainsCalculator::update where a new thread would be launched:

    EAR Monitoring 9+10+3.vst3!ear::plugin::SceneGainsCalculator::update(ear::plugin::proto::SceneStore store) Line 56
    EAR Monitoring 9+10+3.vst3!ear::plugin::MonitoringBackend::updateActiveGains(ear::plugin::proto::SceneStore store) Line 63
    EAR Monitoring 9+10+3.vst3!ear::plugin::MonitoringBackend::onSceneReceived(ear::plugin::proto::SceneStore store) Line 52
    [External Code] 
    EAR Monitoring 9+10+3.vst3!ear::plugin::communication::MonitoringMetadataReceiver::handleReceive::__l9::<lambda_1>::operator()() Line 70
    [External Code] 
    EAR Binaural Monitoring.vst3!nng::detail::AsyncReadAction::operator()() Line 261
    [External Code] 
    EAR Binaural Monitoring.vst3!nng::AsyncIO::callback() Line 227

Bin mon call stack from message received to stack overflow (still on NNG thread)

    EAR Binaural Monitoring.vst3!__chkstk() Line 109    
    EAR Binaural Monitoring.vst3!adm::xml::XmlParser::parse() Line 43
    EAR Binaural Monitoring.vst3!adm::getCommonDefinitions() Line 163   
    EAR Binaural Monitoring.vst3!adm::parseXml(std::basic_istream<char,std::char_traits<char>> & stream, adm::xml::ParserOptions options) Line 18
    EAR Binaural Monitoring.vst3!AdmPresetDefinitionsHelper::AdmPresetDefinitionsHelper() Line 54
    EAR Binaural Monitoring.vst3!AdmPresetDefinitionsHelper::getSingleton() Line 65
    EAR Binaural Monitoring.vst3!ear::plugin::BinauralMonitoringBackend::onSceneReceived(ear::plugin::proto::SceneStore store) Line 228
    [External Code] 
    EAR Binaural Monitoring.vst3!ear::plugin::communication::MonitoringMetadataReceiver::handleReceive(std::error_code ec, nng::Message message) Line 65
    [External Code] 
    EAR Binaural Monitoring.vst3!nng::detail::AsyncReadAction::operator()() Line 261
    [External Code] 
    EAR Binaural Monitoring.vst3!nng::AsyncIO::callback() Line 227

Fix was to launch message handlers in new threads from the common MonitoringMetadataReceiver::handleReceive method.

Closes #277