View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001401 | OpenMPT | Plugins / VST | public | 2020-12-22 17:04 | 2021-01-10 18:30 |
| Reporter | manx | Assigned To | manx | ||
| Priority | high | Severity | minor | Reproducibility | always |
| Status | resolved | Resolution | fixed | ||
| Product Version | OpenMPT 1.30.00.* (old testing) | ||||
| Target Version | OpenMPT 1.30.01.00 / libopenmpt 0.6.0 (upgrade first) | Fixed in Version | OpenMPT 1.30.01.00 / libopenmpt 0.6.0 (upgrade first) | ||
| Summary | 0001401: Do not silently ignore crashes in VST plugins by default any more | ||||
| Description | This had already been discussed before the 1.29 release. | ||||
| Tags | No tags attached. | ||||
| Has the bug occurred in previous versions? | |||||
| Tested code revision (in case you know it) | |||||
|
vst-seh-v10.patch (24,641 bytes)
Index: mptrack/ModDocTemplate.cpp
===================================================================
--- mptrack/ModDocTemplate.cpp (revision 13970)
+++ mptrack/ModDocTemplate.cpp (working copy)
@@ -130,7 +130,7 @@
if(const auto fileExt = filename.GetFileExt(); !mpt::PathString::CompareNoCase(fileExt, P_(".dll")) || !mpt::PathString::CompareNoCase(fileExt, P_(".vst3")))
{
CVstPluginManager *pPluginManager = theApp.GetPluginManager();
- if(pPluginManager && pPluginManager->AddPlugin(filename) != nullptr)
+ if(pPluginManager && pPluginManager->AddPlugin(filename, TrackerSettings::Instance().BrokenPluginsWorkaroundVSTMaskAllCrashes) != nullptr)
{
return nullptr;
}
Index: mptrack/Mptrack.cpp
===================================================================
--- mptrack/Mptrack.cpp (revision 13970)
+++ mptrack/Mptrack.cpp (working copy)
@@ -1847,6 +1847,8 @@
m_pPluginManager = new CVstPluginManager;
const size_t numPlugins = GetSettings().Read<int32>(U_("VST Plugins"), U_("NumPlugins"), 0);
+ bool maskCrashes = TrackerSettings::Instance().BrokenPluginsWorkaroundVSTMaskAllCrashes;
+
std::vector<VSTPluginLib *> nonFoundPlugs;
const mpt::PathString failedPlugin = GetSettings().Read<mpt::PathString>(U_("VST Plugins"), U_("FailedPlugin"), P_(""));
@@ -1911,7 +1913,7 @@
mpt::ustring plugTags = GetSettings().Read<mpt::ustring>(U_("VST Plugins"), tagFormat(plug), mpt::ustring());
bool plugFound = true;
- VSTPluginLib *lib = m_pPluginManager->AddPlugin(plugPath, plugTags, true, &plugFound);
+ VSTPluginLib *lib = m_pPluginManager->AddPlugin(plugPath, maskCrashes, plugTags, true, &plugFound);
if(!plugFound && lib != nullptr)
{
nonFoundPlugs.push_back(lib);
Index: mptrack/SelectPluginDialog.cpp
===================================================================
--- mptrack/SelectPluginDialog.cpp (revision 13970)
+++ mptrack/SelectPluginDialog.cpp (working copy)
@@ -658,7 +658,7 @@
for(const auto &file : dlg.GetFilenames())
{
- VSTPluginLib *lib = plugManager->AddPlugin(file, mpt::ustring(), false);
+ VSTPluginLib *lib = plugManager->AddPlugin(file, TrackerSettings::Instance().BrokenPluginsWorkaroundVSTMaskAllCrashes, mpt::ustring(), false);
if(lib != nullptr)
{
update = true;
@@ -715,6 +715,7 @@
pluginScanDlg.ShowWindow(SW_SHOW);
FolderScanner scan(path, FolderScanner::kOnlyFiles | FolderScanner::kFindInSubDirectories);
+ bool maskCrashes = TrackerSettings::Instance().BrokenPluginsWorkaroundVSTMaskAllCrashes;
mpt::PathString fileName;
int files = 0;
while(scan.Next(fileName) && pluginScanDlg.IsWindowVisible())
@@ -731,7 +732,7 @@
::DispatchMessage(&msg);
}
- VSTPluginLib *lib = pManager->AddPlugin(fileName, mpt::ustring(), false);
+ VSTPluginLib *lib = pManager->AddPlugin(fileName, maskCrashes, mpt::ustring(), false);
if(lib)
{
update = true;
Index: mptrack/TrackerSettings.cpp
===================================================================
--- mptrack/TrackerSettings.cpp (revision 13970)
+++ mptrack/TrackerSettings.cpp (working copy)
@@ -314,6 +314,8 @@
, vstHostProductString(conf, U_("VST Plugins"), U_("HostProductString"), "OpenMPT")
, vstHostVendorString(conf, U_("VST Plugins"), U_("HostVendorString"), "OpenMPT project")
, vstHostVendorVersion(conf, U_("VST Plugins"), U_("HostVendorVersion"), Version::Current().GetRawVersion())
+ // Broken Plugins Workarounds
+ , BrokenPluginsWorkaroundVSTMaskAllCrashes(conf, U_("Broken Plugins Workarounds"), U_("VSTMaskAllCrashes"), true) // TODO: really should be false
// Update
, UpdateEnabled(conf, U_("Update"), U_("Enabled"), true)
, UpdateInstallAutomatically(conf, U_("Update"), U_("InstallAutomatically"), false)
Index: mptrack/TrackerSettings.h
===================================================================
--- mptrack/TrackerSettings.h (revision 13970)
+++ mptrack/TrackerSettings.h (working copy)
@@ -850,6 +850,10 @@
CachedSetting<mpt::lstring> vstHostVendorString;
CachedSetting<int32> vstHostVendorVersion;
+ // Broken Plugins Workarounds
+
+ Setting<bool> BrokenPluginsWorkaroundVSTMaskAllCrashes;
+
// Update
Setting<bool> UpdateEnabled;
Index: mptrack/Vstplug.cpp
===================================================================
--- mptrack/Vstplug.cpp (revision 13970)
+++ mptrack/Vstplug.cpp (working copy)
@@ -19,6 +19,7 @@
#include "AbstractVstEditor.h"
#include "VSTEditor.h"
#include "DefaultVstEditor.h"
+#include "ExceptionHandler.h"
#endif // MODPLUG_TRACKER
#include "../soundlib/Sndfile.h"
#include "../soundlib/MIDIEvents.h"
@@ -29,6 +30,7 @@
#include "../pluginBridge/BridgeOpCodes.h"
#include "../soundlib/plugins/OpCodes.h"
#include "../soundlib/plugins/PluginManager.h"
+#include "../common/mptOSException.h"
using namespace Vst;
DECLARE_FLAGSET(Vst::VstTimeInfoFlags)
@@ -41,55 +43,58 @@
#define VST_LOG
#endif
-// Try loading the VST library.
-static bool LoadLibrarySEH(const mpt::RawPathString &pluginPath, HMODULE &library)
+
+using VstCrash = Windows::SEH::Code;
+
+
+bool CVstPlugin::MaskCrashes() noexcept
{
- __try
- {
- library = LoadLibrary(pluginPath.c_str());
- return true;
- } __except(EXCEPTION_EXECUTE_HANDLER)
- {
- return false;
- }
+ return m_maskCrashes;
}
-static AEffect *CallMainProc(Vst::MainProc pMainProc)
+template <typename Tfn>
+DWORD CVstPlugin::SETryOrError(bool maskCrashes, Tfn fn)
{
- __try
+ DWORD exception = 0;
+ if(maskCrashes)
{
- return pMainProc(CVstPlugin::MasterCallBack);
- } __except(EXCEPTION_EXECUTE_HANDLER)
+ exception = Windows::SEH::TryOrError(fn);
+ if(exception)
+ {
+ ExceptionHandler::TaintProcess(ExceptionHandler::TaintReason::Plugin);
+ }
+ } else
{
- return nullptr;
+ fn();
}
+ return exception;
}
-// Try loading the VST plugin and retrieve the AEffect structure.
-static AEffect *GetAEffectSEH(HMODULE library)
+template <typename Tfn>
+DWORD CVstPlugin::SETryOrError(Tfn fn)
{
- auto pMainProc = (Vst::MainProc)GetProcAddress(library, "VSTPluginMain");
- if(pMainProc == nullptr)
+ DWORD exception = 0;
+ if(MaskCrashes())
{
- pMainProc = (Vst::MainProc)GetProcAddress(library, "main");
- }
-
- if(pMainProc != nullptr)
- {
- return CallMainProc(pMainProc);
+ exception = Windows::SEH::TryOrError(fn);
+ if(exception)
+ {
+ ExceptionHandler::TaintProcess(ExceptionHandler::TaintReason::Plugin);
+ }
} else
{
-#ifdef VST_LOG
- MPT_LOG(LogDebug, "VST", MPT_UFORMAT("Entry point not found! (handle={})")(mpt::ufmt::PTR(library)));
-#endif // VST_LOG
- return nullptr;
+#ifdef MODPLUG_TRACKER
+ ExceptionHandler::ContextSetter ectxguard{&m_Ectx};
+#endif // MODPLUG_TRACKER
+ fn();
}
+ return exception;
}
-AEffect *CVstPlugin::LoadPlugin(VSTPluginLib &plugin, HMODULE &library, bool forceBridge)
+AEffect *CVstPlugin::LoadPlugin(bool maskCrashes, VSTPluginLib &plugin, HMODULE &library, bool forceBridge)
{
const mpt::PathString &pluginPath = plugin.dllPath;
@@ -137,9 +142,17 @@
plugin.useBridge = false;
}
- if(!LoadLibrarySEH(pluginPath.AsNative(), library))
{
- CVstPluginManager::ReportPlugException(MPT_UFORMAT("Exception caught while loading {}")(pluginPath));
+#ifdef MODPLUG_TRACKER
+ ExceptionHandler::Context ectx{ MPT_UFORMAT("VST Plugin: {}")(plugin.dllPath.ToUnicode()) };
+ ExceptionHandler::ContextSetter ectxguard{&ectx};
+#endif // MODPLUG_TRACKER
+ DWORD exception = SETryOrError(maskCrashes, [&](){ library = LoadLibrary(pluginPath.AsNative().c_str()); });
+ if(exception)
+ {
+ CVstPluginManager::ReportPlugException(MPT_UFORMAT("Exception caught while loading {}")(pluginPath));
+ return nullptr;
+ }
}
if(library == nullptr)
{
@@ -167,7 +180,30 @@
if(library != nullptr && library != INVALID_HANDLE_VALUE)
{
- effect = GetAEffectSEH(library);
+ auto pMainProc = (Vst::MainProc)GetProcAddress(library, "VSTPluginMain");
+ if(pMainProc == nullptr)
+ {
+ pMainProc = (Vst::MainProc)GetProcAddress(library, "main");
+ }
+
+ if(pMainProc != nullptr)
+ {
+#ifdef MODPLUG_TRACKER
+ ExceptionHandler::Context ectx{ MPT_UFORMAT("VST Plugin: {}")(plugin.dllPath.ToUnicode()) };
+ ExceptionHandler::ContextSetter ectxguard{&ectx};
+#endif // MODPLUG_TRACKER
+ DWORD exception = SETryOrError(maskCrashes, [&](){ effect = pMainProc(CVstPlugin::MasterCallBack); });
+ if(exception)
+ {
+ return nullptr;
+ }
+ } else
+ {
+#ifdef VST_LOG
+ MPT_LOG(LogDebug, "VST", MPT_UFORMAT("Entry point not found! (handle={})")(mpt::ufmt::PTR(library)));
+#endif // VST_LOG
+ return nullptr;
+ }
}
return effect;
@@ -809,8 +845,9 @@
// CVstPlugin
//
-CVstPlugin::CVstPlugin(HMODULE hLibrary, VSTPluginLib &factory, SNDMIXPLUGIN &mixStruct, AEffect &effect, CSoundFile &sndFile)
+CVstPlugin::CVstPlugin(bool maskCrashes, HMODULE hLibrary, VSTPluginLib &factory, SNDMIXPLUGIN &mixStruct, AEffect &effect, CSoundFile &sndFile)
: IMidiPlugin(factory, sndFile, &mixStruct)
+ , m_maskCrashes(maskCrashes)
, m_Effect(effect)
, timeInfo{}
, isBridged(!memcmp(&effect.reservedForHost2, "OMPT", 4))
@@ -829,6 +866,9 @@
void CVstPlugin::Initialize()
{
+
+ m_Ectx = { MPT_UFORMAT("VST Plugin: {}")(m_Factory.dllPath.ToUnicode()) };
+
// If filename matched during load but plugin ID didn't, make sure it's updated.
m_pMixStruct->Info.dwPluginId1 = m_Factory.pluginId1 = m_Effect.magic;
m_pMixStruct->Info.dwPluginId2 = m_Factory.pluginId2 = m_Effect.uniqueID;
@@ -1020,16 +1060,17 @@
// Wrapper for VST dispatch call with structured exception handling.
-intptr_t CVstPlugin::DispatchSEH(AEffect *effect, VstOpcodeToPlugin opCode, int32 index, intptr_t value, void *ptr, float opt, unsigned long &exception)
+intptr_t CVstPlugin::DispatchSEH(bool maskCrashes, AEffect *effect, VstOpcodeToPlugin opCode, int32 index, intptr_t value, void *ptr, float opt, unsigned long &exception)
{
- __try
+ if(effect->dispatcher != nullptr)
{
- if(effect->dispatcher != nullptr)
+ intptr_t result = 0;
+ DWORD e = SETryOrError(maskCrashes, [&](){ result = effect->dispatcher(effect, opCode, index, value, ptr, opt); });
+ if(e)
{
- return effect->dispatcher(effect, opCode, index, value, ptr, opt);
+ exception = e;
}
- } __except((exception = GetExceptionCode()), EXCEPTION_EXECUTE_HANDLER)
- {
+ return result;
}
return 0;
}
@@ -1037,29 +1078,39 @@
intptr_t CVstPlugin::Dispatch(VstOpcodeToPlugin opCode, int32 index, intptr_t value, void *ptr, float opt)
{
- unsigned long exception = 0;
#ifdef VST_LOG
{
mpt::ustring codeStr;
if(opCode < std::size(VstOpCodes))
+ {
codeStr = mpt::ToUnicode(mpt::Charset::ASCII, VstOpCodes[opCode]);
- else
+ } else
+ {
codeStr = mpt::ufmt::val(opCode);
+ }
MPT_LOG(LogDebug, "VST", MPT_UFORMAT("About to Dispatch({}) (Plugin=\"{}\"), index: {}, value: {}, ptr: {}, opt: {}!\n")(codeStr, m_Factory.libraryName, index, mpt::ufmt::PTR(value), mpt::ufmt::PTR(ptr), mpt::ufmt::flt(opt, 3)));
}
#endif
- intptr_t result = DispatchSEH(&m_Effect, opCode, index, value, ptr, opt, exception);
-
- if(exception)
+ if(!m_Effect.dispatcher)
{
- mpt::ustring codeStr;
- if(opCode < static_cast<int32>(std::size(VstOpCodes)))
- codeStr = mpt::ToUnicode(mpt::Charset::ASCII, VstOpCodes[opCode]);
- else
- codeStr = mpt::ufmt::val(opCode);
- ReportPlugException(MPT_UFORMAT("Exception {} in Dispatch({})")(mpt::ufmt::HEX0<8>(exception), codeStr));
+ return 0;
}
-
+ intptr_t result = 0;
+ {
+ DWORD exception = SETryOrError([&](){ result = m_Effect.dispatcher(&m_Effect, opCode, index, value, ptr, opt); });
+ if(exception)
+ {
+ mpt::ustring codeStr;
+ if(opCode < std::size(VstOpCodes))
+ {
+ codeStr = mpt::ToUnicode(mpt::Charset::ASCII, VstOpCodes[opCode]);
+ } else
+ {
+ codeStr = mpt::ufmt::val(opCode);
+ }
+ ReportPlugException(MPT_UFORMAT("Exception {} in Dispatch({})")(mpt::ufmt::HEX0<8>(exception), codeStr));
+ }
+ }
return result;
}
@@ -1163,11 +1214,9 @@
float fResult = 0;
if(nIndex < m_Effect.numParams && m_Effect.getParameter != nullptr)
{
- __try
+ DWORD exception = SETryOrError([&](){ fResult = m_Effect.getParameter(&m_Effect, nIndex); });
+ if(exception)
{
- fResult = m_Effect.getParameter(&m_Effect, nIndex);
- } __except(EXCEPTION_EXECUTE_HANDLER)
- {
//ReportPlugException(U_("Exception in getParameter (Plugin=\"{}\")!\n"), m_Factory.szLibraryName);
}
}
@@ -1177,16 +1226,15 @@
void CVstPlugin::SetParameter(PlugParamIndex nIndex, PlugParamValue fValue)
{
- __try
+ DWORD exception = 0;
+ if(nIndex < m_Effect.numParams && m_Effect.setParameter)
{
- if(nIndex < m_Effect.numParams && m_Effect.setParameter)
- {
- m_Effect.setParameter(&m_Effect, nIndex, fValue);
- }
- ResetSilence();
- } __except(EXCEPTION_EXECUTE_HANDLER)
+ exception = SETryOrError([&](){ m_Effect.setParameter(&m_Effect, nIndex, fValue); });
+ }
+ ResetSilence();
+ if(exception)
{
- //ReportPlugException(MPT_UFORMAT("Exception in SetParameter({}, {})!")(nIndex, fValue));
+ //ReportPlugException(mpt::format(U_("Exception in SetParameter({}, {})!"))(nIndex, fValue));
}
}
@@ -1273,8 +1321,7 @@
// Process VST events
if(m_Effect.dispatcher != nullptr && vstEvents.Finalise() > 0)
{
- unsigned long exception = 0;
- DispatchSEH(&m_Effect, effProcessEvents, 0, 0, &vstEvents, 0, exception);
+ DWORD exception = SETryOrError([&](){ m_Effect.dispatcher(&m_Effect, effProcessEvents, 0, 0, &vstEvents, 0); });
ResetSilence();
if(exception)
{
@@ -1342,18 +1389,6 @@
}
-// Wrapper for VST process call with structured exception handling.
-static void ProcessSEH(Vst::ProcessProc processFP, AEffect* effect, float** inputs, float** outputs, int32 sampleFrames, unsigned long &exception)
-{
- __try
- {
- processFP(effect, inputs, outputs, sampleFrames);
- } __except((exception = GetExceptionCode()), EXCEPTION_EXECUTE_HANDLER)
- {
- }
-}
-
-
void CVstPlugin::Process(float *pOutL, float *pOutR, uint32 numFrames)
{
ProcessVSTEvents();
@@ -1382,14 +1417,15 @@
}
// Do the VST processing magic
- ASSERT(numFrames <= MIXBUFFERSIZE);
- unsigned long exception = 0;
- ProcessSEH(m_pProcessFP, &m_Effect, m_mixBuffer.GetInputBufferArray(), outputBuffers, numFrames, exception);
- if(exception)
+ MPT_ASSERT(numFrames <= MIXBUFFERSIZE);
{
- Bypass();
- mpt::ustring processMethod = (m_Effect.flags & effFlagsCanReplacing) ? U_("processReplacing") : U_("process");
- ReportPlugException(MPT_UFORMAT("The plugin threw an exception ({}) in {}. It has automatically been set to \"Bypass\".")(mpt::ufmt::HEX0<8>(exception), processMethod));
+ DWORD exception = SETryOrError([&](){ m_pProcessFP(&m_Effect, m_mixBuffer.GetInputBufferArray(), outputBuffers, numFrames); });
+ if(exception)
+ {
+ Bypass();
+ mpt::ustring processMethod = (m_Effect.flags & effFlagsCanReplacing) ? U_("processReplacing") : U_("process");
+ ReportPlugException(MPT_UFORMAT("The plugin threw an exception ({}) in {}. It has automatically been set to \"Bypass\".")(mpt::ufmt::HEX0<8>(exception), processMethod));
+ }
}
// Mix outputs of multi-output VSTs:
Index: mptrack/Vstplug.h
===================================================================
--- mptrack/Vstplug.h (revision 13970)
+++ mptrack/Vstplug.h (working copy)
@@ -19,7 +19,11 @@
#include "../soundlib/Mixer.h"
#include "plugins/VstDefinitions.h"
#include "plugins/VstEventQueue.h"
+#if defined(MODPLUG_TRACKER)
+#include "ExceptionHandler.h"
+#endif // MODPLUG_TRACKER
+
OPENMPT_NAMESPACE_BEGIN
@@ -31,6 +35,8 @@
class CVstPlugin final : public IMidiPlugin
{
protected:
+
+ bool m_maskCrashes;
HMODULE m_hLibrary;
Vst::AEffect &m_Effect;
Vst::ProcessProc m_pProcessFP = nullptr; // Function pointer to AEffect processReplacing if supported, else process.
@@ -49,13 +55,29 @@
Vst::VstTimeInfo timeInfo;
public:
+
const bool isBridged : 1; // True if our built-in plugin bridge is being used.
+private:
+
+#if defined(MODPLUG_TRACKER)
+ ExceptionHandler::Context m_Ectx;
+#endif // MODPLUG_TRACKER
+
public:
- CVstPlugin(HMODULE hLibrary, VSTPluginLib &factory, SNDMIXPLUGIN &mixPlugin, Vst::AEffect &effect, CSoundFile &sndFile);
+ bool MaskCrashes() noexcept;
+
+public:
+ template <typename Tfn> static DWORD SETryOrError(bool maskCrashes, Tfn fn);
+
+private:
+ template <typename Tfn> DWORD SETryOrError(Tfn fn);
+
+public:
+ CVstPlugin(bool maskCrashes, HMODULE hLibrary, VSTPluginLib &factory, SNDMIXPLUGIN &mixPlugin, Vst::AEffect &effect, CSoundFile &sndFile);
~CVstPlugin();
- static Vst::AEffect *LoadPlugin(VSTPluginLib &plugin, HMODULE &library, bool forceBridge);
+ static Vst::AEffect *LoadPlugin(bool maskCrashes, VSTPluginLib &plugin, HMODULE &library, bool forceBridge);
protected:
void Initialize();
@@ -91,7 +113,7 @@
CString GetParamLabel(PlugParamIndex param) override { return GetParamPropertyString(param, Vst::effGetParamLabel); };
CString GetParamDisplay(PlugParamIndex param) override { return GetParamPropertyString(param, Vst::effGetParamDisplay); };
- static intptr_t DispatchSEH(Vst::AEffect *effect, Vst::VstOpcodeToPlugin opCode, int32 index, intptr_t value, void *ptr, float opt, unsigned long &exception);
+ static intptr_t DispatchSEH(bool maskCrashes, Vst::AEffect *effect, Vst::VstOpcodeToPlugin opCode, int32 index, intptr_t value, void *ptr, float opt, unsigned long &exception);
intptr_t Dispatch(Vst::VstOpcodeToPlugin opCode, int32 index, intptr_t value, void *ptr, float opt);
bool HasEditor() const override { return (m_Effect.flags & Vst::effFlagsHasEditor) != 0; }
Index: soundlib/plugins/PluginManager.cpp
===================================================================
--- soundlib/plugins/PluginManager.cpp (revision 13970)
+++ soundlib/plugins/PluginManager.cpp (working copy)
@@ -55,6 +55,7 @@
#include "../../mptrack/TrackerSettings.h"
#include "../../mptrack/AbstractVstEditor.h"
#include "../../soundlib/AudioCriticalSection.h"
+#include "../mptrack/ExceptionHandler.h"
#include "../common/mptCRC.h"
#endif // MODPLUG_TRACKER
@@ -427,10 +428,10 @@
// Extract instrument and category information from plugin.
#ifndef NO_VST
-static void GetPluginInformation(Vst::AEffect *effect, VSTPluginLib &library)
+static void GetPluginInformation(bool maskCrashes, Vst::AEffect *effect, VSTPluginLib &library)
{
unsigned long exception = 0;
- library.category = static_cast<VSTPluginLib::PluginCategory>(CVstPlugin::DispatchSEH(effect, Vst::effGetPlugCategory, 0, 0, nullptr, 0, exception));
+ library.category = static_cast<VSTPluginLib::PluginCategory>(CVstPlugin::DispatchSEH(maskCrashes, effect, Vst::effGetPlugCategory, 0, 0, nullptr, 0, exception));
library.isInstrument = ((effect->flags & Vst::effFlagsIsSynth) || !effect->numInputs);
if(library.isInstrument)
@@ -443,7 +444,7 @@
#ifdef MODPLUG_TRACKER
std::vector<char> s(256, 0);
- CVstPlugin::DispatchSEH(effect, Vst::effGetVendorString, 0, 0, s.data(), 0, exception);
+ CVstPlugin::DispatchSEH(maskCrashes, effect, Vst::effGetVendorString, 0, 0, s.data(), 0, exception);
library.vendor = mpt::ToCString(mpt::Charset::Locale, s.data());
#endif // MODPLUG_TRACKER
}
@@ -452,7 +453,7 @@
#ifdef MODPLUG_TRACKER
// Add a plugin to the list of known plugins.
-VSTPluginLib *CVstPluginManager::AddPlugin(const mpt::PathString &dllPath, const mpt::ustring &tags, bool fromCache, bool *fileFound)
+VSTPluginLib *CVstPluginManager::AddPlugin(const mpt::PathString &dllPath, bool maskCrashes, const mpt::ustring &tags, bool fromCache, bool *fileFound)
{
const mpt::PathString fileName = dllPath.GetFileName();
@@ -535,32 +536,39 @@
unsigned long exception = 0;
// Always scan plugins in a separate process
HINSTANCE hLib = NULL;
- Vst::AEffect *pEffect = CVstPlugin::LoadPlugin(*plug, hLib, true);
-
- if(pEffect != nullptr && pEffect->magic == Vst::kEffectMagic && pEffect->dispatcher != nullptr)
{
- CVstPlugin::DispatchSEH(pEffect, Vst::effOpen, 0, 0, 0, 0, exception);
+#ifdef MODPLUG_TRACKER
+ ExceptionHandler::Context ectx{ MPT_UFORMAT("VST Plugin: {}")(plug->dllPath.ToUnicode()) };
+ ExceptionHandler::ContextSetter ectxguard{&ectx};
+#endif // MODPLUG_TRACKER
- plug->pluginId1 = pEffect->magic;
- plug->pluginId2 = pEffect->uniqueID;
+ Vst::AEffect *pEffect = CVstPlugin::LoadPlugin(maskCrashes, *plug, hLib, true);
- GetPluginInformation(pEffect, *plug);
+ if(pEffect != nullptr && pEffect->magic == Vst::kEffectMagic && pEffect->dispatcher != nullptr)
+ {
+ CVstPlugin::DispatchSEH(maskCrashes, pEffect, Vst::effOpen, 0, 0, 0, 0, exception);
+ plug->pluginId1 = pEffect->magic;
+ plug->pluginId2 = pEffect->uniqueID;
+
+ GetPluginInformation(maskCrashes, pEffect, *plug);
+
#ifdef VST_LOG
- intptr_t nver = CVstPlugin::DispatchSEH(pEffect, Vst::effGetVstVersion, 0,0, nullptr, 0, exception);
- if (!nver) nver = pEffect->version;
- MPT_LOG(LogDebug, "VST", MPT_UFORMAT("{}: v{}.0, {} in, {} out, {} programs, {} params, flags=0x{} realQ={} offQ={}")(
- plug->libraryName, nver,
- pEffect->numInputs, pEffect->numOutputs,
- mpt::ufmt::dec0<2>(pEffect->numPrograms), mpt::ufmt::dec0<2>(pEffect->numParams),
- mpt::ufmt::HEX0<4>(static_cast<int32>(pEffect->flags)), pEffect->realQualities, pEffect->offQualities));
+ intptr_t nver = CVstPlugin::DispatchSEH(maskCrashes, pEffect, Vst::effGetVstVersion, 0,0, nullptr, 0, exception);
+ if (!nver) nver = pEffect->version;
+ MPT_LOG(LogDebug, "VST", MPT_UFORMAT("{}: v{}.0, {} in, {} out, {} programs, {} params, flags=0x{} realQ={} offQ={}")(
+ plug->libraryName, nver,
+ pEffect->numInputs, pEffect->numOutputs,
+ mpt::ufmt::dec0<2>(pEffect->numPrograms), mpt::ufmt::dec0<2>(pEffect->numParams),
+ mpt::ufmt::HEX0<4>(static_cast<int32>(pEffect->flags)), pEffect->realQualities, pEffect->offQualities));
#endif // VST_LOG
- CVstPlugin::DispatchSEH(pEffect, Vst::effClose, 0, 0, 0, 0, exception);
+ CVstPlugin::DispatchSEH(maskCrashes, pEffect, Vst::effClose, 0, 0, 0, 0, exception);
- validPlug = true;
+ validPlug = true;
+ }
+
}
-
FreeLibrary(hLib);
if(exception != 0)
{
@@ -672,6 +680,8 @@
}
#ifdef MODPLUG_TRACKER
+ bool maskCrashes = TrackerSettings::Instance().BrokenPluginsWorkaroundVSTMaskAllCrashes;
+
if(!pFound && (mixPlugin.GetLibraryName() != U_("")))
{
// Try finding the plugin DLL in the plugin directory or plugin cache instead.
@@ -682,7 +692,7 @@
}
fullPath += mpt::PathString::FromUnicode(mixPlugin.GetLibraryName()) + P_(".dll");
- pFound = AddPlugin(fullPath);
+ pFound = AddPlugin(fullPath, maskCrashes);
if(!pFound)
{
// Try plugin cache (search for library name)
@@ -696,7 +706,7 @@
fullPath = theApp.PathInstallRelativeToAbsolute(fullPath);
if(fullPath.IsFile())
{
- pFound = AddPlugin(fullPath);
+ pFound = AddPlugin(fullPath, maskCrashes);
}
}
}
@@ -710,18 +720,18 @@
HINSTANCE hLibrary = nullptr;
bool validPlugin = false;
- pEffect = CVstPlugin::LoadPlugin(*pFound, hLibrary, TrackerSettings::Instance().bridgeAllPlugins);
+ pEffect = CVstPlugin::LoadPlugin(maskCrashes, *pFound, hLibrary, TrackerSettings::Instance().bridgeAllPlugins);
if(pEffect != nullptr && pEffect->dispatcher != nullptr && pEffect->magic == Vst::kEffectMagic)
{
validPlugin = true;
- GetPluginInformation(pEffect, *pFound);
+ GetPluginInformation(maskCrashes, pEffect, *pFound);
// Update cached information
pFound->WriteToCache();
- CVstPlugin *pVstPlug = new (std::nothrow) CVstPlugin(hLibrary, *pFound, mixPlugin, *pEffect, sndFile);
+ CVstPlugin *pVstPlug = new (std::nothrow) CVstPlugin(maskCrashes, hLibrary, *pFound, mixPlugin, *pEffect, sndFile);
if(pVstPlug == nullptr)
{
validPlugin = false;
Index: soundlib/plugins/PluginManager.h
===================================================================
--- soundlib/plugins/PluginManager.h (revision 13970)
+++ soundlib/plugins/PluginManager.h (working copy)
@@ -160,7 +160,7 @@
size_t size() const { return pluginList.size(); }
bool IsValidPlugin(const VSTPluginLib *pLib) const;
- VSTPluginLib *AddPlugin(const mpt::PathString &dllPath, const mpt::ustring &tags = mpt::ustring(), bool fromCache = true, bool *fileFound = nullptr);
+ VSTPluginLib *AddPlugin(const mpt::PathString &dllPath, bool maskCrashes, const mpt::ustring &tags = mpt::ustring(), bool fromCache = true, bool *fileFound = nullptr);
bool RemovePlugin(VSTPluginLib *);
bool CreateMixPlugin(SNDMIXPLUGIN &, CSoundFile &);
void OnIdle();
|
|
|
Comited as r13996 (1.30.00.23). |
|
|
Forum thread: https://forum.openmpt.org/index.php?topic=6537.0 |
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2020-12-22 17:04 | manx | New Issue | |
| 2020-12-22 17:04 | manx | Status | new => assigned |
| 2020-12-22 17:04 | manx | Assigned To | => manx |
| 2020-12-22 17:04 | manx | Relationship added | related to 0001291 |
| 2020-12-22 17:05 | manx | Note Added: 0004557 | |
| 2020-12-22 17:05 | manx | File Added: vst-seh-v10.patch | |
| 2020-12-22 17:06 | manx | Status | assigned => feedback |
| 2020-12-30 09:22 | manx | Note Added: 0004584 | |
| 2020-12-30 11:04 | manx | Note Added: 0004587 | |
| 2021-01-10 18:28 | manx | Status | feedback => resolved |
| 2021-01-10 18:28 | manx | Resolution | open => fixed |
| 2021-01-10 18:28 | manx | Fixed in Version | => OpenMPT 1.30.01.00 / libopenmpt 0.6.0 (upgrade first) |