Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove all cairo usage from RunLoop and fix #334 (open/close editor c… #337

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

rehans
Copy link
Contributor

@rehans rehans commented Feb 1, 2025

Like discussed here: #335 (comment)

I stress tested on reaper without any crash.

@ryukau @madah81pnz1 Probably you can do another testing as well

@scheffle
Copy link
Collaborator

scheffle commented Feb 1, 2025

This does not look right. The DrawHandler is not the owner of the device and thus should not remove it.
A CairoGraphicsDeviceFactory instance is a member of the LinuxFactory::Impl and that one should make sure that all devices are cleared and this should be happening when VSTGUI::exit is called. Doesn't it work without removing the device from the device factory?

@scheffle
Copy link
Collaborator

scheffle commented Feb 1, 2025

OK, forget my last comment. Currently the DrawHandler adds the device in its constructor. So this looks ok for now.

@rehans
Copy link
Contributor Author

rehans commented Feb 1, 2025

Just for explanation:

When I do not call removeDevice the destructor of CairoGraphicsDevice is not being called. Reason for that is that CairoGraphicsDeviceFactory holds a devices list of smart pointers to CairoGraphicsDevice. Closing the editor does not "destroy" the CairoGraphicsDeviceFactory and keeps all CairoGraphicsDevice "alive".

VSTGUI::exit is not called when closing the editor but only when the plug-in is unloaded entirely.

@ryukau
Copy link

ryukau commented Feb 1, 2025

The patch works fine here. Thank you.

@madah81pnz1
Copy link

I tested with this commit in Reaper, but I could still get a crash when clicking open/close UI for two plugin instances:

Thread 1 "reaper" received signal SIGSEGV, Segmentation fault.
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x14bc6d8, __in_chrg=<optimized out>) at /usr/include/c++/14/bits/shared_ptr_base.h:1069
1069		  _M_pi->_M_release();
(gdb) bt
#0  std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x14bc6d8, __in_chrg=<optimized out>) at /usr/include/c++/14/bits/shared_ptr_base.h:1069
#1  std::__shared_ptr<VSTGUI::CairoGraphicsDevice, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x14bc6d0, __in_chrg=<optimized out>)
    at /usr/include/c++/14/bits/shared_ptr_base.h:1525
#2  std::shared_ptr<VSTGUI::CairoGraphicsDevice>::~shared_ptr (this=0x14bc6d0, __in_chrg=<optimized out>) at /usr/include/c++/14/bits/shared_ptr.h:175
#3  std::__new_allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> >::destroy<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > (this=0x24f6c50, __p=0x14bc6d0)
    at /usr/include/c++/14/bits/new_allocator.h:198
#4  std::allocator_traits<std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > >::destroy<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > (__a=..., __p=0x14bc6d0)
    at /usr/include/c++/14/bits/alloc_traits.h:591
#5  std::vector<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > >::_M_erase (this=0x24f6c50, __position=Python Exception <class 'gdb.error'>: value has been optimized out
)
    at /usr/include/c++/14/bits/vector.tcc:187
#6  std::vector<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > >::erase (this=0x24f6c50, __position=Python Exception <class 'gdb.error'>: value has been optimized out
)
    at /usr/include/c++/14/bits/stl_vector.h:1537
#7  VSTGUI::CairoGraphicsDeviceFactory::removeDevice (this=this@entry=0x1840460, device=<optimized out>)
    at /home/matte/dev/common/vstgui_github/vstgui/lib/platform/linux/cairographicscontext.cpp:86
#8  0x00007ffff3179cf5 in VSTGUI::X11::DrawHandler::~DrawHandler (this=0x199c5b8, __in_chrg=<optimized out>)
    at /home/matte/dev/common/vstgui_github/vstgui/lib/platform/linux/x11frame.cpp:183
#9  VSTGUI::X11::Frame::Impl::~Impl (this=0x199c590, __in_chrg=<optimized out>) at /home/matte/dev/common/vstgui_github/vstgui/lib/platform/linux/x11frame.cpp:339
#10 std::default_delete<VSTGUI::X11::Frame::Impl>::operator() (this=<optimized out>, __ptr=0x199c590) at /usr/include/c++/14/bits/unique_ptr.h:93
#11 std::__uniq_ptr_impl<VSTGUI::X11::Frame::Impl, std::default_delete<VSTGUI::X11::Frame::Impl> >::reset (this=0x2bf9568, __p=0x0)
    at /usr/include/c++/14/bits/unique_ptr.h:205
#12 std::unique_ptr<VSTGUI::X11::Frame::Impl, std::default_delete<VSTGUI::X11::Frame::Impl> >::reset (this=0x2bf9568, __p=0x0) at /usr/include/c++/14/bits/unique_ptr.h:504
#13 VSTGUI::X11::Frame::~Frame (this=0x2bf9540, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/matte/dev/common/vstgui_github/vstgui/lib/platform/linux/x11frame.cpp:657
#14 VSTGUI::X11::Frame::~Frame (this=0x2bf9540, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/matte/dev/common/vstgui_github/vstgui/lib/platform/linux/x11frame.cpp:659
#15 0x00007ffff3134f84 in VSTGUI::SharedPointer<VSTGUI::IPlatformFrame>::operator= (this=0x1994350, _ptr=0x0)
    at /home/matte/dev/common/vstgui_github/vstgui/lib/vstguibase.h:442
#16 VSTGUI::CFrame::close (this=0x16675c0) at /home/matte/dev/common/vstgui_github/vstgui/lib/cframe.cpp:198

@madah81pnz1
Copy link

madah81pnz1 commented Feb 2, 2025

Valgrind shows this:

==19798== Invalid read of size 8
==19798==    at 0x2C426EF4: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:1068)
==19798==    by 0x2C4BC4DF: std::__shared_ptr<VSTGUI::CairoGraphicsDevice, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:1525)
==19798==    by 0x2C4BC4FB: std::shared_ptr<VSTGUI::CairoGraphicsDevice>::~shared_ptr() (shared_ptr.h:175)
==19798==    by 0x2C4BEEB8: destroy<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > (new_allocator.h:198)
==19798==    by 0x2C4BEEB8: destroy<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > (alloc_traits.h:591)
==19798==    by 0x2C4BEEB8: std::vector<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > >::_M_erase(__gnu_cxx::__normal_iterator<std::shared_ptr<VSTGUI::CairoGraphicsDevice>*, std::vector<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > > >) (vector.tcc:187)
==19798==    by 0x2C4BDA7A: std::vector<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > >::erase(__gnu_cxx::__normal_iterator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> const*, std::vector<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > > >) (stl_vector.h:1537)
==19798==    by 0x2C4B644E: VSTGUI::CairoGraphicsDeviceFactory::removeDevice(_cairo_device*) (cairographicscontext.cpp:86)
==19798==    by 0x2C4CFB7F: VSTGUI::X11::DrawHandler::~DrawHandler() (x11frame.cpp:183)
==19798==    by 0x2C4D076A: VSTGUI::X11::Frame::Impl::~Impl() (x11frame.cpp:339)
==19798==    by 0x2C4D2C27: std::default_delete<VSTGUI::X11::Frame::Impl>::operator()(VSTGUI::X11::Frame::Impl*) const (unique_ptr.h:93)
==19798==    by 0x2C4D2CCF: std::__uniq_ptr_impl<VSTGUI::X11::Frame::Impl, std::default_delete<VSTGUI::X11::Frame::Impl> >::reset(VSTGUI::X11::Frame::Impl*) (unique_ptr.h:205)
==19798==    by 0x2C4D2402: std::unique_ptr<VSTGUI::X11::Frame::Impl, std::default_delete<VSTGUI::X11::Frame::Impl> >::reset(VSTGUI::X11::Frame::Impl*) (unique_ptr.h:504)
==19798==    by 0x2C4CEA2E: VSTGUI::X11::Frame::~Frame() (x11frame.cpp:657)
==19798==  Address 0x7f231c8 is 8 bytes before a block of size 16 alloc'd
==19798==    at 0x4843F93: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==19798==    by 0x2C4C295F: std::__new_allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> >::allocate(unsigned long, void const*) (new_allocator.h:151)
==19798==    by 0x2C4C0ED8: allocate (alloc_traits.h:509)
==19798==    by 0x2C4C0ED8: std::_Vector_base<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > >::_M_allocate(unsigned long) (stl_vector.h:380)
==19798==    by 0x2C4BFE56: void std::vector<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > >::_M_realloc_append<std::shared_ptr<VSTGUI::CairoGraphicsDevice> >(std::shared_ptr<VSTGUI::CairoGraphicsDevice>&&) (vector.tcc:596)
==19798==    by 0x2C4BEBDA: std::shared_ptr<VSTGUI::CairoGraphicsDevice>& std::vector<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > >::emplace_back<std::shared_ptr<VSTGUI::CairoGraphicsDevice> >(std::shared_ptr<VSTGUI::CairoGraphicsDevice>&&) (vector.tcc:123)
==19798==    by 0x2C4BD699: std::vector<std::shared_ptr<VSTGUI::CairoGraphicsDevice>, std::allocator<std::shared_ptr<VSTGUI::CairoGraphicsDevice> > >::push_back(std::shared_ptr<VSTGUI::CairoGraphicsDevice>&&) (stl_vector.h:1301)
==19798==    by 0x2C4B633C: VSTGUI::CairoGraphicsDeviceFactory::addDevice(_cairo_device*) (cairographicscontext.cpp:76)
==19798==    by 0x2C4CFA6E: VSTGUI::X11::DrawHandler::DrawHandler(VSTGUI::X11::ChildWindow const&) (x11frame.cpp:176)
==19798==    by 0x2C4D0586: VSTGUI::X11::Frame::Impl::Impl(unsigned long, VSTGUI::CPoint, VSTGUI::IPlatformFrameCallback*) (x11frame.cpp:333)
==19798==    by 0x2C4CE818: VSTGUI::X11::Frame::Frame(VSTGUI::IPlatformFrameCallback*, VSTGUI::CRect const&, unsigned int, VSTGUI::IPlatformFrameConfig*) (x11frame.cpp:649)
==19798==    by 0x2C4A1BE4: VSTGUI::SharedPointer<VSTGUI::X11::Frame> VSTGUI::makeOwned<VSTGUI::X11::Frame, VSTGUI::IPlatformFrameCallback*&, VSTGUI::CRect const&, unsigned long&, VSTGUI::IPlatformFrameConfig*&>(VSTGUI::IPlatformFrameCallback*&, VSTGUI::CRect const&, unsigned long&, VSTGUI::IPlatformFrameConfig*&) (vstguibase.h:470)
==19798==    by 0x2C4A08F3: VSTGUI::LinuxFactory::createFrame(VSTGUI::IPlatformFrameCallback*, VSTGUI::CRect const&, void*, VSTGUI::PlatformType, VSTGUI::IPlatformFrameConfig*) const (linuxfactory.cpp:96)

@rehans
Copy link
Contributor Author

rehans commented Feb 2, 2025

Sorry, my bad! 🤦‍♂️

Should be fixed, please try again!

Btw, how do you test two plug-in editors?

I do:

  1. Start reaper and create an audio track
  2. Click on "FX" button on the track
  3. Add FX (2x AGain.vst3) to the track
  4. Right click on the 2nd AGain.vst3 (in chain view) and select "Window float selected FX" (another editor opens up)
  5. Click on the 1st AGain.vst3 in the list of the chain view to make it visible
  6. Open/close both editors in different order

Any other way of testing it?

@ryukau
Copy link

ryukau commented Feb 2, 2025

After applying the latest commit, AGain crashed when opening 2 windows from 2 different plugin instances. This might be a separate issue as the backtrace suggests something is wrong on timer.

I used debug build of AGain on Reaper on Ubuntu. The same crash happened on release build, however it was hard to reproduce. It seems that the crash happens when closing the window. A video is attached to the bottom of this comment.

Below are the error messages right after the crash.

/home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/platform/linux/x11timer.cpp:38: Assertion 'runLoop' failed. Timer only works of run loop was set
reaper: /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguidebug.cpp:124: void VSTGUI::doAssert(const char*, const char*, const char*, const char*): Assertion `false' failed.
Aborted (core dumped)

Below is backtrace from gdb:

Core was generated by `./reaper'.
Program terminated with signal SIGABRT, Aborted.

(gdb) bt
#0  __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=0) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007225d244519e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007225d2428902 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007225d242881e in __assert_fail_base
    (fmt=0x7225d25de2a0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x7225a5725410 "false", file=file@entry=0x7225a57253c8 "/home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguidebug.cpp", line=line@entry=124, function=function@entry=0x7225a5725378 "void VSTGUI::doAssert(const char*, const char*, const char*, const char*)") at ./assert/assert.c:94
#6  0x00007225d243b7c7 in __assert_fail
    (assertion=0x7225a5725410 "false", file=0x7225a57253c8 "/home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguidebug.cpp", line=124, function=0x7225a5725378 "void VSTGUI::doAssert(const char*, const char*, const char*, const char*)") at ./assert/assert.c:103
#7  0x00007225a564eff2 in VSTGUI::doAssert
    (filename=0x7225a57271f8 "/home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/platform/linux/x11timer.cpp", line=0x7225a572724c "38", condition=0x7225a57271ed "runLoop", desc=0x7225a57271c8 "Timer only works of run loop was set")
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguidebug.cpp:124
#8  0x00007225a5681f33 in VSTGUI::X11::Timer::stop (this=0xa7a9a40)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/platform/linux/x11timer.cpp:38
#9  0x00007225a564bd0f in VSTGUI::CVSTGUITimer::stop (this=0xa4de2b0)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/cvstguitimer.cpp:80
#10 0x00007225a564bbd0 in VSTGUI::CVSTGUITimer::beforeDelete (this=0xa4de2b0)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/cvstguitimer.cpp:55
#11 0x00007225a5326d06 in VSTGUI::ReferenceCounted<int>::forget (this=0xa4de2b0)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:269
#12 0x00007225a56548a6 in VSTGUI::Animation::Detail::Timer::~Timer
    (this=0xa4e5d90, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:167
#13 0x00007225a5654906 in VSTGUI::Animation::Detail::Timer::~Timer
    (this=0xa4e5d90, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:169
#14 0x00007225a5326d1e in VSTGUI::ReferenceCounted<int>::forget (this=0xa4e5d90)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:269
#15 0x00007225a56545a3 in VSTGUI::Animation::Detail::Timer::removeAnimator (animator=0xb1a9690)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:136
#16 0x00007225a5653058 in VSTGUI::Animation::Animator::~Animator
    (this=0xb1a9690, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:260
#17 0x00007225a565309e in VSTGUI::Animation::Animator::~Animator
    (this=0xb1a9690, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:261
#18 0x00007225a5326d1e in VSTGUI::ReferenceCounted<int>::forget (this=0xb1a9690)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:269
#19 0x00007225a55a664e in VSTGUI::SharedPointer<VSTGUI::Animation::Animator>::operator= (this=0xaf63960, _ptr=0x0)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:441
#20 0x00007225a559ce86 in VSTGUI::CFrame::beforeDelete (this=0xa5c6f40)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/cframe.cpp:152
#21 0x00007225a5326d06 in VSTGUI::ReferenceCounted<int>::forget (this=0xa5c6f40)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:269
#22 0x00007225a559d0d8 in VSTGUI::CFrame::close (this=0xa5c6f40)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/cframe.cpp:200
#23 0x00007225a5317b66 in VSTGUI::VST3Editor::close() () at /home/cu/.vst3/again.vst3/Contents/x86_64-linux/again.so
#24 0x00007225a5332548 in Steinberg::Vst::VSTGUIEditor::removed() ()
    at /home/cu/.vst3/again.vst3/Contents/x86_64-linux/again.so
2025-02-02.20-23-48.mp4

@madah81pnz1
Copy link

Nice work! With the latest commit, 27ec53a (Check for end iterator before using it), I don't get a crash anymore. I only tested my own plugin, not AGain.vst3.

Though sometimes I get flooded with these printouts:

the target surface has been finished
the target surface has been finished
the target surface has been finished
the target surface has been finished

Adding two instances of the same plugin to the same track in Reaper is basically how I tested this also. Then I quickly bash the UI button on both of them randomly, which switches between Reaper's internal UI (parameter list) and the plugin's own UI.

A small thing; The commit message should be updated to say "fix #334", since #335 was my pull request that didn't work out. If you put "Fixes #334" on its own line, github will automatically close the issue when the pull request is merged.

@rehans
Copy link
Contributor Author

rehans commented Feb 2, 2025

After applying the latest commit, AGain crashed when opening 2 windows from 2 different plugin instances. This might be a separate issue as the backtrace suggests something is wrong on timer.

I used debug build of AGain on Reaper on Ubuntu. The same crash happened on release build, however it was hard to reproduce. It seems that the crash happens when closing the window. A video is attached to the bottom of this comment.

Below are the error messages right after the crash.

/home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/platform/linux/x11timer.cpp:38: Assertion 'runLoop' failed. Timer only works of run loop was set
reaper: /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguidebug.cpp:124: void VSTGUI::doAssert(const char*, const char*, const char*, const char*): Assertion `false' failed.
Aborted (core dumped)

Below is backtrace from gdb:

Core was generated by `./reaper'.
Program terminated with signal SIGABRT, Aborted.

(gdb) bt
#0  __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=0) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007225d244519e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007225d2428902 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007225d242881e in __assert_fail_base
    (fmt=0x7225d25de2a0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x7225a5725410 "false", file=file@entry=0x7225a57253c8 "/home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguidebug.cpp", line=line@entry=124, function=function@entry=0x7225a5725378 "void VSTGUI::doAssert(const char*, const char*, const char*, const char*)") at ./assert/assert.c:94
#6  0x00007225d243b7c7 in __assert_fail
    (assertion=0x7225a5725410 "false", file=0x7225a57253c8 "/home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguidebug.cpp", line=124, function=0x7225a5725378 "void VSTGUI::doAssert(const char*, const char*, const char*, const char*)") at ./assert/assert.c:103
#7  0x00007225a564eff2 in VSTGUI::doAssert
    (filename=0x7225a57271f8 "/home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/platform/linux/x11timer.cpp", line=0x7225a572724c "38", condition=0x7225a57271ed "runLoop", desc=0x7225a57271c8 "Timer only works of run loop was set")
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguidebug.cpp:124
#8  0x00007225a5681f33 in VSTGUI::X11::Timer::stop (this=0xa7a9a40)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/platform/linux/x11timer.cpp:38
#9  0x00007225a564bd0f in VSTGUI::CVSTGUITimer::stop (this=0xa4de2b0)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/cvstguitimer.cpp:80
#10 0x00007225a564bbd0 in VSTGUI::CVSTGUITimer::beforeDelete (this=0xa4de2b0)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/cvstguitimer.cpp:55
#11 0x00007225a5326d06 in VSTGUI::ReferenceCounted<int>::forget (this=0xa4de2b0)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:269
#12 0x00007225a56548a6 in VSTGUI::Animation::Detail::Timer::~Timer
    (this=0xa4e5d90, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:167
#13 0x00007225a5654906 in VSTGUI::Animation::Detail::Timer::~Timer
    (this=0xa4e5d90, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:169
#14 0x00007225a5326d1e in VSTGUI::ReferenceCounted<int>::forget (this=0xa4e5d90)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:269
#15 0x00007225a56545a3 in VSTGUI::Animation::Detail::Timer::removeAnimator (animator=0xb1a9690)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:136
#16 0x00007225a5653058 in VSTGUI::Animation::Animator::~Animator
    (this=0xb1a9690, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:260
#17 0x00007225a565309e in VSTGUI::Animation::Animator::~Animator
    (this=0xb1a9690, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/animation/animator.cpp:261
#18 0x00007225a5326d1e in VSTGUI::ReferenceCounted<int>::forget (this=0xb1a9690)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:269
#19 0x00007225a55a664e in VSTGUI::SharedPointer<VSTGUI::Animation::Animator>::operator= (this=0xaf63960, _ptr=0x0)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:441
#20 0x00007225a559ce86 in VSTGUI::CFrame::beforeDelete (this=0xa5c6f40)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/cframe.cpp:152
#21 0x00007225a5326d06 in VSTGUI::ReferenceCounted<int>::forget (this=0xa5c6f40)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/vstguibase.h:269
#22 0x00007225a559d0d8 in VSTGUI::CFrame::close (this=0xa5c6f40)
    at /home/cu/code/VSTPlugins/lib/vst3sdk/vstgui4/vstgui/lib/cframe.cpp:200
#23 0x00007225a5317b66 in VSTGUI::VST3Editor::close() () at /home/cu/.vst3/again.vst3/Contents/x86_64-linux/again.so
#24 0x00007225a5332548 in Steinberg::Vst::VSTGUIEditor::removed() ()
    at /home/cu/.vst3/again.vst3/Contents/x86_64-linux/again.so

2025-02-02.20-23-48.mp4

Yes, I know this one, it is a different issue. The animated "Open UI Editor" button on the top left corner is causing this (though the reason is something else). If you close the editor while the animation of this button is running the assert is triggered. I already investigated into this but could not fix this "quickly". It needs some more effort. But first, let's get this one ready ;)

@rehans rehans changed the title Remove all cairo usage from RunLoop and fix #335 (open/close editor c… Remove all cairo usage from RunLoop and fix #334 (open/close editor c… Feb 2, 2025
@rehans
Copy link
Contributor Author

rehans commented Feb 2, 2025

Nice work! With the latest commit, 27ec53a (Check for end iterator before using it), I don't get a crash anymore. I only tested my own plugin, not AGain.vst3.

Though sometimes I get flooded with these printouts:

the target surface has been finished
the target surface has been finished
the target surface has been finished
the target surface has been finished

Should be fine I assume. I did not see this message but this is what we do basically.

Adding two instances of the same plugin to the same track in Reaper is basically how I tested this also. Then I quickly bash the UI button on both of them randomly, which switches between Reaper's internal UI (parameter list) and the plugin's own UI.

Yes, quite similar to my stress test, good!

A small thing; The commit message should be updated to say "fix #334", since #335 was my pull request that didn't work out. If you put "Fixes #334" on its own line, github will automatically close the issue when the pull request is merged.

Done!

@ryukau
Copy link

ryukau commented Feb 2, 2025

@rehans That's okay, at least the plugins are usable now. Thanks again for this fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants