How to kill Cubase with JUCE Plug-In(s) OpenGL & Some locks (Windows)


#1

So I got this report from a user, after being able to reproduce this with our old “write shaders yourself” code I’ve went up and been able to trace this as related to JUCE Messaging and Locking.

Reproducing:
(My machine is i7-6800k with nVidia GTX750 32GB RAM, Windows 10 and I’ve tested Cubase 9.0.1)

  1. So first create a new Audio Plug-in from Projucer (I’ve used latest development commit #daab51
    as of writing this).

  2. Add 3 lines,

  • an OpenGLContext mCtx with your private variables (Editor.h)
  • In your constructor: mCtx.attachTo(*this);
  • In your destructor: mCtx.detach()
  1. Compile and copy .dll to your vstplugins folder. (I’ve tested also VST3, it’s not a wrapper thing)

  2. Open Cubase with a new empty project.

  3. Create 32 Audio Tracks (you can do even less though)

  4. Open MixConsole (F3)

  5. Select all audio tracks (from the area on your left, shift-click)

  6. Toggle the QLink button on the upper right corner (this will duplicate your behavior to all tracks).

  7. Open the Inserts view, and Insert our shiny new plugin.

Prepare to restart your machine or at least Ctrl+Alt+Del hoping Cubase will crash before your machine totally freeze.

Debugging?
It is kinda tricky for me the system would stuck so it is very hard to properly profile or find a decent stack.

Profiling? Adding debugger to the blend would even make your machine freeze deeper…
Eventually after few minutes I’ve been able to get Task Manager and to discover my Debugger Monitor crashed…

With OpenGL crash:
Some threads would stuck on MessageManager::Lock::BlockingMessage::messageCallback()

With OpenGL you might see many threads with:
DeleteGL.dll!juce::OpenGLContext::NativeContext::deactivateCurrentContext() Line 100|C++| | |DeleteGL.dll!juce::OpenGLContext::deactivateCurrentContext() Line 947|C++| | |DeleteGL.dll!juce::OpenGLContext::CachedImage::renderFrame() Line 276|C++| | |DeleteGL.dll!juce::OpenGLContext::CachedImage::runJob() Line 463|C++| | |DeleteGL.dll!juce::ThreadPool::runNextJob(juce::ThreadPool::ThreadPoolThread & thread) Line 389|C++| | |DeleteGL.dll!juce::ThreadPool::ThreadPoolThread::run() Line 37|C++| | |DeleteGL.dll!juce::Thread::threadEntryPoint() Line 96|C++| | |DeleteGL.dll!juce::juce_threadEntryPoint(void * userData) Line 119|C++|

Regression:

It’s been with JUCE for a lot of years now. Tested our JUCE 3.x plugins, our JUCE 4.2 ones. All till latest master would behave the same.

Without OpenGL:

Without using OpenGL you’ll feel some freezing and responsiveness issues but it won’t make your machine freeze.

A Cubase issue?
I’ve tested the same workflow with Waves plug-ins. They handles it without a problem. (they do use OpenGL)

Wonder how I can continue further. it’s definitely some nasty racing / message bombarding. but it’s tricky to nail down.

Update #1:
Apparently I didn’t copy the non-OpenGL dll the first time. so I’ve updated this post to properly mention OpenGL as part of the blame.

Update #2:
On macOS this won’t reproduce.