xris1658 / yadaw

Yet Another Digital Audio Workstation
GNU General Public License v3.0
18 stars 1 forks source link

Crashes on unloading Zebra2 / Zebralette #1

Closed xris1658 closed 6 months ago

xris1658 commented 6 months ago

Zebra2 and Zebralette are synthesizers by u-he.

Reproduce

Error message

Exception 0xc0000005 encountered at address 0x7ff85cfcfe78: Access violation reading location 0xffffffffffffffff

Stack trace

Module Name Address
Zebra2(x64).vst3 0x00007ff85cfcfe78
Zebra2(x64).vst3 0x00007ff85cfc402a
Zebra2(x64).vst3 0x00007ff85cfc3ea4
Zebra2(x64).vst3 0x00007ff85cfc3775
VST3Test.exe releasePointer<Steinberg::Vst::IComponent>(Steinberg::Vst::IComponent *) VST3Helper.hpp:27
VST3Test.exe YADAW::Audio::Plugin::VST3Plugin::destroyPlugin() VST3Plugin.cpp:138
VST3Test.exe YADAW::Audio::Plugin::VST3Plugin::~VST3Plugin() VST3Plugin.cpp:159
VST3Test.exe main(int, char **) main.cpp:459
VST3Test.exe invoke_main() 0x00007ff6ab62a839
VST3Test.exe __scrt_common_main_seh() 0x00007ff6ab62a78e
VST3Test.exe __scrt_common_main() 0x00007ff6ab62a64e
VST3Test.exe mainCRTStartup(void *) 0x00007ff6ab62a8ae
kernel32.dll 0x00007ff8d3e47344
ntdll.dll 0x00007ff8d5de26b1

More details

xris1658 commented 6 months ago

Changes in commit 941119b6 has been reverted since it crashes on Linux. The evasion is definitely not the desired way to fix the issue.

xris1658 commented 6 months ago

This issue is fixed in commit 23fec17f.

The reason why this issue occurred is that the Steinberg::IPlugView tries to access VST3PluginGUI::frame_ that passed to the IPlugView before when ctor of VST3PluginGUI is called. This happens even if the IPlugView::release() is called indirectly in VST3Plugin::uninitializeEditController() (by checking the ref count, we noticed that the IPlugView is still alive).

Actually, I located this problem pretty quickly by using Dr. Memory, which found this illegal access:

~~Dr.M~~ Error #855: UNADDRESSABLE ACCESS of freed memory: reading 0x00000287a6b68dc8-0x00000287a6b68dd0 8 byte(s)
~~Dr.M~~ # 0 Zebra2(x64).dll!AM_VST3_Processor::process12092+0xb2b5   (0x00007ffcd97ffe75 <Zebra2(x64).dll+0x48fe75>)
~~Dr.M~~ # 1 Zebra2(x64).dll!ExitDll                      +0x234d99 (0x00007ffcd97f402a <Zebra2(x64).dll+0x48402a>)
~~Dr.M~~ # 2 Zebra2(x64).dll!ExitDll                      +0x234c13 (0x00007ffcd97f3ea4 <Zebra2(x64).dll+0x483ea4>)
~~Dr.M~~ # 3 Zebra2(x64).dll!ExitDll                      +0x2344e4 (0x00007ffcd97f3775 <Zebra2(x64).dll+0x483775>)
~~Dr.M~~ # 4 releasePointer<>                              [C:\Users\xris1658\Project\YADAW\src\audio\util\VST3Helper.hpp:34]
~~Dr.M~~ # 5 invoke_main                                   [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78]
~~Dr.M~~ # 6 __scrt_common_main_seh                        [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
~~Dr.M~~ # 7 __scrt_common_main                            [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:330]
~~Dr.M~~ # 8 mainCRTStartup                                [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:16]
~~Dr.M~~ # 9 KERNEL32.dll!BaseThreadInitThunk             +0x13     (0x00007ffd34707344 <KERNEL32.dll+0x17344>)
~~Dr.M~~ Note: @0:01:33.453 in thread 14968
~~Dr.M~~ Note: next higher malloc: 0x00000287a6b69620-0x00000287a6b69720
~~Dr.M~~ Note: 0x00000287a6b68dc8-0x00000287a6b68dd0 overlaps memory 0x00000287a6b68db0-0x00000287a6b68df0 that was freed here:
~~Dr.M~~ Note: # 0 replace_operator_delete_nothrow                                            [D:\a\drmemory\drmemory\common\alloc_replace.c:2978]
~~Dr.M~~ Note: # 1 operator delete                                                            [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\heap\delete_scalar_size.cpp:31]
~~Dr.M~~ Note: # 2 YADAW::Audio::Plugin::VST3PluginGUI::`scalar deleting destructor'
~~Dr.M~~ Note: # 3 std::unique_ptr<>::reset                                                   [C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\memory:3284]
~~Dr.M~~ Note: # 4 YADAW::Audio::Plugin::VST3Plugin::uninitializeEditController               [C:\Users\xris1658\Project\YADAW\src\audio\plugin\VST3Plugin.cpp:654]
~~Dr.M~~ Note: # 5 YADAW::Audio::Plugin::VST3Plugin::uninitialize                             [C:\Users\xris1658\Project\YADAW\src\audio\plugin\VST3Plugin.cpp:300]
~~Dr.M~~ Note: instruction: mov    (%rcx) -> %rax

In which the read is actually where VST3PluginGUI::frame_ is at.

xris1658 commented 6 months ago

I mentioned previously that Musec does not crash on unloading these plugins, even if it did not reset the frame (see here). This is because the frame object is a stack object inside VST3Plugin (see here). Therefore, the frame object will survive the plugin instance. The old design hides mistakes I have made, only to trip me and confuse me later.

xris1658 commented 6 months ago

The same goes for the component handler, which is why the commit above exists. The first commit fixed the issue in VST3Test while the second commit fixed the issue in the main app.