Windows DLL插件加载时崩溃

时间:2019-12-01 09:09:22

标签: c++ windows dll cmake juce

正在寻找一些有关在加载dll时在Windows中导致此类崩溃的建议。

enter image description here

我正在用C ++编写Windows VST3 .dll插件,并在加载.dll时启动时崩溃。通过Visual Studio 2019调试器运行主机应用程序和插件时,我得到上面的Access violation executing location ...对话框,并且调用堆栈为空,使我认为内存已完全损坏。

也许这是由于构建.dll时需要调整的链接选项引起的?

以下是一些事实:

  • 插件本身可以正常工作。当所有第三方API调用都被注释掉时,我可以轻松地加载和卸载它。
  • 如果我将一些第三方库链接到我的插件中,那么一切都将正常运行。
  • 一旦我调用了这些第三方库的 any ,就会导致启动时出现段错误。
  • 插件是使用/ MD构建的,但是我也尝试过/ MT并看到了相同的行为。
  • 我正在使用JUCE C ++来获取VST3框架和GUI组件。
  • SuperpoweredSDK C ++库是我要链接并尝试调用的第三方库之一的示例。但是我尝试了其他库,但每个库的行为都相同。

不幸的是,将整个空白的VST3插件放在一起是太多代码,无法在StackOverflow问题中发布。但是由于如果我注释掉对第三方库的所有调用,就可以使插件正常工作,所以我认为代码本身不是问题,因此我认为dll(.vst3)文件的构建方式是问题所在。 / p>

用于构建.vst3 dll文件的CMakeLists.txt文件的关键部分如下所示:

FIND_LIBRARY ( SuperpoweredSDK NAMES SuperpoweredWin141_Debug_MD_x64.lib PATHS ${SUPERPOWERED_DIR}/libWindows )
SET ( TEST_EXTERNAL_DEPS PRIVATE Threads::Threads ${SuperpoweredSDK} )

FILE ( GLOB JUCE_SOURCE ${CMAKE_HOME_DIRECTORY}/JuceLibraryCode/*.cpp )
LIST ( FILTER JUCE_SOURCE EXCLUDE REGEX ".+/JuceLibraryCode/include_juce_audio_plugin_client_[^u].+" )

FILE ( GLOB PLUGIN_SOURCE *.cpp )

ADD_LIBRARY ( TestVST3 SHARED ${JUCE_SOURCE} ${PLUGIN_SOURCE} ${CMAKE_HOME_DIRECTORY}/JuceLibraryCode/include_juce_audio_plugin_client_VST3.cpp )
SET_TARGET_PROPERTIES ( TestVST3 PROPERTIES OUTPUT_NAME "Test" SUFFIX ".vst3" )
TARGET_LINK_LIBRARIES ( TestVST3 PUBLIC ${TEST_EXTERNAL_DEPS} )

2 个答案:

答案 0 :(得分:0)

  

加载dll时在Windows中会导致此类崩溃的原因

典型原因是某些全局变量的初始化程序。加载DLL时将崩溃的示例代码:

class C
{
public:
    C() { __debugbreak(); } // Compiles into `int 3` interrupt, will definitely crash
};
static C g_c;

当您链接外部库但不调用它时,链接器的无效代码清除功能通常会删除完整的.obj文件,这些文件已链接但未使用。这也会在其中放置变量及其构造函数。

一种调试方式,在DllMain上设置断点。但实际上并未导出您代码中的DllMain,而是另一个。在VC ++ 2017 CRT中,一个称为dllmain_dispatch,其源文件在VC ++运行时crt\src\vcruntime\dll_dllmain.cpp中。该dllmain_dispatch会在调用您的DllMain之前调用几个函数,其中一个dllmain_crt_process_attach会调用_initterm,而实际上是调用所有全局函数的构造函数。在您的情况下,其中至少有一个失败。

P.S。这样的崩溃的可能原因,您的第三方库正在尝试使用COM,而名为LoadLibrary的线程从未调用CoInitialize()。

答案 1 :(得分:0)

我们最终确实找到了崩溃的原因。使用VST3文件,DAW将加载每个.dll(或.vst3),查询功能,然后立即再次卸载该dll。然后将其移至下一个文件,整个过程重新开始,直到查询了所有插件为止。

在这种情况下,我使用的第三个第三方库之一(SuperpoweredSDK)启动了一个后台线程,以针对某处的Web服务器验证许可证。没有记录。启动后台线程后,DAW会在不知不觉中继续卸载DLL,从而使线程挂在那儿并运行不再存在的代码!因此,崩溃没有任何调用堆栈。

几种可能的解决方案:

  • 移动SuperpoweredSDK初始化代码,直到稍后真正需要它时为止。
  • 在将来尚未发行的SuperpoweredSDK版本(当前版本为2.0.1)中,他们显然是在添加API调用以关闭Superpowered,并且该关闭调用将等待所有后台线程运行完毕。确保调用此新API。
相关问题