On plugin instantiation failure, `Lv2Proc::m_valid` was being set to false. However, `Lv2Proc::run` did not evaluate `m_valid` and still called `lilv_instance_run`, which caused undefined behavior, including crashes. This bug fixes this by not even create such zombie classes, and instead `throw`s right away. The throws are caught in `lmms_plugin_main`, as suggested in the PR discussion and as the VST3 approach.
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "Lv2Effect.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "Lv2SubPluginFeatures.h"
|
||||
|
||||
@@ -109,9 +110,12 @@ extern "C"
|
||||
PLUGIN_EXPORT Plugin *lmms_plugin_main(Model *_parent, void *_data)
|
||||
{
|
||||
using KeyType = Plugin::Descriptor::SubPluginFeatures::Key;
|
||||
auto eff = new Lv2Effect(_parent, static_cast<const KeyType*>(_data));
|
||||
if (!eff->isValid()) { delete eff; eff = nullptr; }
|
||||
return eff;
|
||||
try {
|
||||
return new Lv2Effect(_parent, static_cast<const KeyType*>(_data));
|
||||
} catch (const std::runtime_error& e) {
|
||||
qCritical() << e.what();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,8 +41,6 @@ public:
|
||||
initialization
|
||||
*/
|
||||
Lv2Effect(Model* parent, const Descriptor::SubPluginFeatures::Key* _key);
|
||||
//! Must be checked after ctor or reload
|
||||
bool isValid() const { return m_controls.isValid(); }
|
||||
|
||||
bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override;
|
||||
EffectControls* controls() override { return &m_controls; }
|
||||
|
||||
@@ -38,11 +38,8 @@ Lv2FxControls::Lv2FxControls(class Lv2Effect *effect, const QString& uri) :
|
||||
EffectControls(effect),
|
||||
Lv2ControlBase(this, uri)
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
connect(Engine::audioEngine(), &AudioEngine::sampleRateChanged,
|
||||
this, [this](){onSampleRateChanged();});
|
||||
}
|
||||
connect(Engine::audioEngine(), &AudioEngine::sampleRateChanged,
|
||||
this, &Lv2FxControls::onSampleRateChanged);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -76,19 +76,16 @@ Lv2Instrument::Lv2Instrument(InstrumentTrack *instrumentTrackArg,
|
||||
Instrument(instrumentTrackArg, &lv2instrument_plugin_descriptor, key),
|
||||
Lv2ControlBase(this, key->attributes["uri"])
|
||||
{
|
||||
if (Lv2ControlBase::isValid())
|
||||
{
|
||||
clearRunningNotes();
|
||||
clearRunningNotes();
|
||||
|
||||
connect(instrumentTrack()->pitchRangeModel(), SIGNAL(dataChanged()),
|
||||
this, SLOT(updatePitchRange()), Qt::DirectConnection);
|
||||
connect(Engine::audioEngine(), &AudioEngine::sampleRateChanged,
|
||||
this, [this](){onSampleRateChanged();});
|
||||
connect(instrumentTrack()->pitchRangeModel(), SIGNAL(dataChanged()),
|
||||
this, SLOT(updatePitchRange()), Qt::DirectConnection);
|
||||
connect(Engine::audioEngine(), &AudioEngine::sampleRateChanged,
|
||||
this, &Lv2Instrument::onSampleRateChanged);
|
||||
|
||||
// now we need a play-handle which cares for calling play()
|
||||
auto iph = new InstrumentPlayHandle(this, instrumentTrackArg);
|
||||
Engine::audioEngine()->addPlayHandle(iph);
|
||||
}
|
||||
// now we need a play-handle which cares for calling play()
|
||||
auto iph = new InstrumentPlayHandle(this, instrumentTrackArg);
|
||||
Engine::audioEngine()->addPlayHandle(iph);
|
||||
}
|
||||
|
||||
|
||||
@@ -134,11 +131,6 @@ void Lv2Instrument::onSampleRateChanged()
|
||||
|
||||
|
||||
|
||||
bool Lv2Instrument::isValid() const { return Lv2ControlBase::isValid(); }
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2Instrument::saveSettings(QDomDocument &doc, QDomElement &that)
|
||||
{
|
||||
Lv2ControlBase::saveSettings(doc, that);
|
||||
@@ -321,9 +313,12 @@ extern "C"
|
||||
PLUGIN_EXPORT Plugin *lmms_plugin_main(Model *_parent, void *_data)
|
||||
{
|
||||
using KeyType = Plugin::Descriptor::SubPluginFeatures::Key;
|
||||
auto ins = new Lv2Instrument(static_cast<InstrumentTrack*>(_parent), static_cast<KeyType*>(_data));
|
||||
if (!ins->isValid()) { delete ins; ins = nullptr; }
|
||||
return ins;
|
||||
try {
|
||||
return new Lv2Instrument(static_cast<InstrumentTrack*>(_parent), static_cast<KeyType*>(_data));
|
||||
} catch (const std::runtime_error& e) {
|
||||
qCritical() << e.what();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,8 +61,6 @@ public:
|
||||
~Lv2Instrument() override;
|
||||
void reload();
|
||||
void onSampleRateChanged();
|
||||
//! Must be checked after ctor or reload
|
||||
bool isValid() const;
|
||||
|
||||
/*
|
||||
load/save
|
||||
|
||||
Reference in New Issue
Block a user