osxmidi / LinVst

Linux Windows vst wrapper/bridge
GNU General Public License v3.0
682 stars 41 forks source link

Some plugins crash Bitwig's audio engine #105

Closed robbert-vdh closed 5 years ago

robbert-vdh commented 5 years ago

I've come across a few plugins that seem to lock Bitwig's entire audio engine up while working just fine in other hosts. When this happens the entire JACK server locks up and Bitwig won't play back any audio anymore, even after forcefully killing and restarting JACK. Bitwig doesn't seem to offer any ways to show plugin output so I haven't been able to properly debug this.

This happens on at least Bitwig 2.4 through 3.0.2 (2.4 was the earliest version I used LinVst with), LinVst 2.5+ and with all versions of Wine I've used since then. In a few instances the GUIs will show up just fine, but the audio engine always locks up as soon as the plugin's done loading.

Affected plugins

Other hosts that don't have this issue

osxmidi commented 5 years ago

Have you tried this

For Bitwig 2.5 and 3.0, In Settings->Plug-ins choose "Individually" plugin setting and check all of the LinVst plugins. For Bitwig 2.4.3, In Settings->Plug-ins choose Independent plug-in host process for "Each plug-in" setting and check all of the LinVst plugins.

robbert-vdh commented 5 years ago

Yes, this happens for all different sandboxing settings. I would try to fix this myself but I have no clue how to debug VST plugins in Bitwig.

EDIT: I've at least managed to get some kind of backtrace. The plugins are probably just behaving differently from what LinVst expects as the process freezes while Bitwig's querying the plugin's parameter display values. This is what I get when attaching GDB to BitwigPluginHost64 when compiling LinVst with debug symbols and without optimizations:

$ pid=""; while [ "$pid" == "" ]; do pid=$(pgrep -o BitwigPlugin); done; sudo gdb -p $pid
GNU gdb (GDB) 8.3
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 25626
[New LWP 25628]
[New LWP 25629]
[New LWP 25630]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
0x00007f538252de3d in syscall () from /usr/lib/libc.so.6
(gdb) c
Continuing.
^C
Thread 1 "BitwigPluginHos" received signal SIGINT, Interrupt.
0x00007f538252de3d in syscall () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007f538252de3d in syscall () from /usr/lib/libc.so.6
#1  0x00007f53827e4083 in RemotePluginClient::fwait (this=0xeb8040, futexp=0x7f538278f004, ms=0)
    at remotepluginclient.cpp:2699
#2  0x00007f53827e21d4 in RemotePluginClient::waitForServer5 (this=0xeb8040) at remotepluginclient.cpp:1622
#3  0x00007f53827e12bd in RemotePluginClient::getEffString (this=0xeb8040, opcode=7, index=1, ptr=0x7ffd005245e0 "", len=64)
    at remotepluginclient.cpp:1226
#4  0x00007f53827dafb4 in dispatcher (effect=0xeb8070, opcode=7, index=1, value=0, ptr=0x7ffd005245e0, opt=0)
    at linvst.cpp:614
#5  0x000000000051c2c9 in Vst2PluginInstance::getParameterDisplay(PluginParameterInfo*) ()
#6  0x00000000005599b6 in ?? ()
#7  0x000000000055c6f8 in ?? ()
#8  0x000000000054668d in PluginHost::runRequest(PluginHostRequest*) ()
#9  0x0000000000536303 in ?? ()
#10 0x0000000000502bd1 in base::core::Epoll::wait(int) ()
#11 0x000000000053786d in PluginHost::run() ()
#12 0x00000000004cdd4f in main ()

For now I've simply changed removed the infinite loop from fwait and I've changed the timeout from a minute to half a second and that does the trick, but I'm not sure how this is supposed to work.

osxmidi commented 5 years ago

From that it seems that getEffString is causing a problem.

I've altered the getEffString code, so if you try it out could you let me know if that fixes it.

robbert-vdh commented 5 years ago

The same thing still happens. I'm not sure what's supposed to be happening in RemotePluginClient::fwait, but the infinite loop there causes these plugins to hang. Here's another backtrace! (compiled without optimizations)

Backtrace ```shell ^C Thread 1 "BitwigPluginHos" received signal SIGINT, Interrupt. 0x00007f42c97ace3d in syscall () from /usr/lib/libc.so.6 (gdb) bt #0 0x00007f42c97ace3d in syscall () from /usr/lib/libc.so.6 #1 0x00007f42c9a630b5 in RemotePluginClient::fwait (this=0x1f7b040, futexp=0x7f42c9a0e004, ms=0) at remotepluginclient.cpp:2698 #2 0x00007f42c9a61206 in RemotePluginClient::waitForServer5 (this=0x1f7b040) at remotepluginclient.cpp:1621 #3 0x00007f42c9a60317 in RemotePluginClient::getEffString[abi:cxx11](int, int) (this=0x1f7b040, opcode=7, index=1) at remotepluginclient.cpp:1226 #4 0x00007f42c9a59fdf in dispatcher (effect=0x1f7b070, opcode=7, index=1, value=0, ptr=0x7fffdca2efe0, opt=0) at linvst.cpp:612 #5 0x000000000051c2c9 in Vst2PluginInstance::getParameterDisplay(PluginParameterInfo*) () #6 0x00000000005599b6 in ?? () #7 0x000000000055c6f8 in ?? () #8 0x000000000054668d in PluginHost::runRequest(PluginHostRequest*) () #9 0x0000000000536303 in ?? () #10 0x0000000000502bd1 in base::core::Epoll::wait(int) () #11 0x000000000053786d in PluginHost::run() () #12 0x00000000004cdd4f in main () ```
osxmidi commented 5 years ago

I've changed some routines.

robbert-vdh commented 5 years ago

It's still happening. I've also included a backtrace for the other plugin. That plugin gets stuck in the same infinite loop but when opening the GUI instead of when being queried for parameter values.

BigClipper backtrace ```shell (gdb) bt #0 0x00007f6612a0ee3d in syscall () from /usr/lib/libc.so.6 #1 0x00007f6612cc5203 in RemotePluginClient::fwait (this=0x201a040, futexp=0x7f6612c74004, ms=0) at remotepluginclient.cpp:2723 #2 0x00007f6612cc2f38 in RemotePluginClient::waitForServer3 (this=0x201a040) at remotepluginclient.cpp:1580 #3 0x00007f6612cc2982 in RemotePluginClient::getParameterDisplay[abi:cxx11](int) (this=0x201a040, p=1) at remotepluginclient.cpp:1326 #4 0x00007f6612cbbfc7 in dispatcher (effect=0x201a070, opcode=7, index=1, value=0, ptr=0x7ffdfd882520, opt=0) at linvst.cpp:613 #5 0x000000000051c2c9 in Vst2PluginInstance::getParameterDisplay(PluginParameterInfo*) () #6 0x00000000005599b6 in ?? () #7 0x000000000055c6f8 in ?? () #8 0x000000000054668d in PluginHost::runRequest(PluginHostRequest*) () #9 0x0000000000536303 in ?? () #10 0x0000000000502bd1 in base::core::Epoll::wait(int) () #11 0x000000000053786d in PluginHost::run() () #12 0x00000000004cdd4f in main () ```
Gain Reduction Deluxe backtrace ```shell (gdb) bt #0 0x00007f8cbe5fde3d in syscall () from /usr/lib/libc.so.6 #1 0x00007f8cbe8b4203 in RemotePluginClient::fwait (this=0x9530c0, futexp=0x7f8cbe863004, ms=0) at remotepluginclient.cpp:2723 #2 0x00007f8cbe8b1f38 in RemotePluginClient::waitForServer3 (this=0x9530c0) at remotepluginclient.cpp:1580 #3 0x00007f8cbe8b2b10 in RemotePluginClient::showGUI (this=0x9530c0) at remotepluginclient.cpp:2064 #4 0x00007f8cbe8ab19e in dispatcher (effect=0x9530f0, opcode=14, index=0, value=0, ptr=0x8c00000, opt=0) at linvst.cpp:793 #5 0x000000000053f0a9 in PluginInstance::openGUI(unsigned int, bool, base::core::String, bool, int, int, bool, int, int, double, int, int, int, int) () #6 0x000000000055befd in ?? () #7 0x000000000055c6f8 in ?? () #8 0x000000000054668d in PluginHost::runRequest(PluginHostRequest*) () #9 0x0000000000536303 in ?? () #10 0x0000000000502bd1 in base::core::Epoll::wait(int) () #11 0x000000000053786d in PluginHost::run() () #12 0x00000000004cdd4f in main () ```

Both plugins still work just fine through Carla instead of Bitwig.

osxmidi commented 5 years ago

I tested BigClipper and it crashes with Bitwig but not with other DAWs like you say.

I can't open the BigClipper GUI because of the crash that happens I assume.

robbert-vdh commented 5 years ago

I have gotten BigClipper's GUI to open in the past after I had removed the infinite loop from RemotePluginClient::fwait (and thus sort of bypassed the whole effGetParamDisplay thing), but I don't really understand what's happening over there so I haven't been able to try my hand at fixing this.

osxmidi commented 5 years ago

From what I can find out, Bitwig seems to be loading the dll and causing a false positive with the audioMasterProcessEvents opcode which makes the plugin crash.

If the audioMasterProcessEvents routine is disabled in lin-vst-server.cpp then it seems to load ok.

When loaded in Reaper the plugin doesn't call audioMasterProcessEvents but somehow Bitwig is falsely triggering it and that could be anything, Bitwig/Wine/Library incompatibilities with what LinVst is doing.

robbert-vdh commented 5 years ago

Why has this been closed? There's still a spinlock causing certain plugins to hang indefinitely.

gilfuser commented 5 years ago

Hi @robbert-vdh

How did you do this backtrace?

I've being having a similar issue with LinVST with SuperCollider through VSTPlugin and would like to find out what's going on, or at least to who I need to ask for help.

robbert-vdh commented 5 years ago

I used GDB for the backtrace. GDB can do a ton of stuff, so you'll probably have reading up to do haha. Since LinVST freezes without crashing you could simply attach the debugger to the running BitwigPluginHost64 process, but I used something like this to attach the debugger to the first BitwigPluginHost64 that appeared:

pid=''; while [ "$pid" == "" ]; do pid=$(pgrep -o BitwigPlugin); done; sudo gdb -p $pid

After attaching the debugger you can use c[ontinue] to resume the process, Ctrl+C to suspend the process again after it crashes, and bt to generate a backtrace. When you do this you should compile LinVST without optimizations and with debug symbols, or else the output might not be very useful. You can do this by changing all instances of -O2 in the makefile to -g and then recompiling and reinstalling.