[Resolved] JUCE Timer crash when closing Cubase project

I was testing my latest builds (using JUCE 5.3.2), and saw my host (Cubase 10) crash when I closed my project, without quitting Cubase, and with my plugin still open. The crash log shows this:

Crashed Thread:        33  JUCE Timer

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x00000001299d4ffe
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

VM Regions Near 0x1299d4ffe:
    MALLOC_LARGE           000000012959a000-000000012991a000 [ 3584K] rw-/rwx SM=PRV  
--> 
    mapped file            000000012bc4e000-000000012bdad000 [ 1404K] r-x/rwx SM=COW  


Thread 33 Crashed:: JUCE Timer
0   ???                           	0x00000001299d4ffe 0 + 4993142782
1   ???                           	0x00000001299ff51b 0 + 4993316123
2   ???                           	0x00000001299dad6c 0 + 4993166700
3   libsystem_pthread.dylib       	0x00007fff6e912661 _pthread_body + 340
4   libsystem_pthread.dylib       	0x00007fff6e91250d _pthread_start + 377
5   libsystem_pthread.dylib       	0x00007fff6e911bf9 thread_start + 13

I don’t recall seeing this before, and don’t know of any changes that I have made that are related to the timer. My processor and editor classes both derive publicly from Timer, so they should destroy themselves normally, shouldn’t they? Is there something I need to do in my classes’ destructors to prevent the timers from firing and leading to this crash? Do I have to loop until the timer callbacks exit (checking a member flag that I set on entry and reset on exit to the timer callbacks)?

EDIT: I added stopTimer() calls at the start of my destructors, and also added guards around the code in the timer callbacks to ensure they aren’t re-entered, and even added a loop in the destructor to make sure the timer callbacks had finished before proceeding with the destructor code, but none of those helps. I still get JUCE Time crashes when closing my project in Cubase 10 with my plugin open.

Have you tried attaching the debugger to Cubase while it’s running (not tried it myself but it should be possible, only Pro Tools has problems with debuggers I’ve found…)? That should show you what line is causing the problem

If you’re using Xcode you can select “Edit Scheme” for the VST/VST3 scheme you’re using and then set the executable to the /Applications/Cubase.app bundle. Or if you want to start Cubase first then attach, there’s the “Debug -> Attach To Process” menu

I found it. Not sure exactly how it caused a crash, but running from the command line showed me a bunch of leaked objects stemming from our look&feel-derived class. Turns out we were not calling reset() on that pointer, so it was leaking. Apparently (guessing), this also led to code in it being called somehow when the plugin was being torn down. Now the leak is plugged and the crash is gone. Whew!

You shouldn’t have to call reset(), it is called automatically, when the stack is rolled back.
If you have a unique_ptr, that leaks if you don’t call reset(), that indicates that the stack/object that owns the unique_ptr itself isn’t destroyed.
Calling for JUCE_DECLARE_NON_COPYABLE_AND_LEAK_DETECTOR or JUCE_ADD_LEAK_DETECTOR.

The editor class (derived from AudioProcessorEditor) is the one that owns this pointer. If it’s not being destroyed, then that would be a host bug, right? Or is the processor class supposed to delete it? It is created in createEditor(), but simply returned from that function, not stored as a member in my derived processor class. Is that not correct?

I already have the macro JUCE_DECLARE_NON_COPYABLE_AND_LEAK_DETECTOR(myeditorclass) at the end of my AudioProcessorEditor-derived class. That class, however, is two generations down from AudioProcessorEditor, and the class between then does not have that. Does that class need that also (despite the fact it does not contain any of these std::unique_ptr members)?

However, I just noticed that my view components that are members of my editor (also as std::unique_ptr<>) all set the pointers to nullptr in the destructor, rather than calling reset() on them. Should I be doing that (instead)?

No, indeed. The host owns the editor and is responsible to delete that, especially to do so before the processor is deleted. This is especially crucial, since the processor reference in the editor becomes invalid, once the processor is deleted.
But that means also IMHO, that it seems unlikely, that a host would keep an editor around without the corresponding processor.

That is identical, afaik. There is no need to change that.

I found that this is not fixed by that change. When quitting Cubase (10.0.20.141), it properly destroys the plugin’s editor component. But when simply closing the project, if the plugin window is open, then it crashes after leaking everything related to our LookAndFeel object. (I don’t actually know who created all these leaked objects, but there are many. Our LookAndFeel object is the only one I know the source of.)

When debugging, after stepping through all of those leak assertions, the stack trace gets reduced to just “start” and then the crash, with no indication of any associated C++ code at all.

EDIT: I have reported this to the Steinberg/Yamaha beta team, and am downloading a newer build to see if it fixes the issue.

1 Like

The latest beta release (which was the release candidate) fixed the issue. Yay!