Latest juce.Plugin demo hangs host on closing when UI opened

The mistery is even worse: the plugin that shows the crash when compiled in debug mode, works flawlessly when compiled as release.

Since it is the biggest and slowest plugin we have, I fear the crash is caused by some kind of race condition, that is triggered by the fact that the editor in debug mode takes some time to be completely deleted.

clean build ?

Salvator

[quote=“Salvator”]clean build ?

Salvator[/quote]

Done, but the problem remains.

Investigating the selector that caused the problem, I think I found the cause: when compiled in Debug mode, the plugin creates an auxiliary window that isn’t child of it.

Sure enough, the EditorComponent’s destructor contains the code to deallocate that auxiliary window as well, but for some reason I have no time to investigate (here Jules may have more luck than me), it seems that it behaves correctly only when I explicitly close the editor AND THEN delete the plugin from live.

If I let the host do all the work upon deletion of the plugin, leaving the EditorComponent window open, I am sure (verified with the debugger) that the EditorComponent destructor gets called, but for some reason I fear that OS X “remembers” some reference to that auxiliary window, and attempts to send a message to that after having deleted it.

Well, I suppose you could try explicitly closing the window before releasing it… although I think that might not work. If you want to try it, you’d just have to add a [hostWindow close] call in the ComponentInHIView destructor just before [hostWindow release]

(And maybe try [pluginWindow close] too)

Though I’m pretty sure I remember playing around with this already.

Hi, it seems that I have something to add to this thread =)

I have a nice crash in Protools LE 8, mac os x 10.5.6,

and my RTAS plugin is killing PT if I trying to do this steps -

I have previously saved PT project, plugin is inserted in one of the insert slots in mixer.
Plugin UI is closed.

So, I open this project, and perform opening and closing of plugin editor as fast as I can.
For this - just move mixer to the left so that opened plugin UI will not hide mixer, and double click on corresponding mixer insert.
Plugin will show up for a fraction of second and hide.

After that - if I try to open plugin UI once more time - PT dies.

I’m postin it in this thread, because after commenting out

for (int i = 20; --i >= 0;)
    MessageManager::getInstance()->runDispatchLoopUntil (1);

at the end of removeSubWindow in juce_RTAS_MacUtilities.mm all is working fine. But in that case, closing PT with active plugin UI kills PT.

This is an part of call stack from crash report.

Process: Pro Tools LE [986]
Path: /Applications/Digidesign/Pro Tools/Pro Tools LE.app/Contents/MacOS/Pro Tools LE
Identifier: com.digidesign.ProToolsLE
Version: 8.0.3 (8.0.3f249)
Code Type: X86 (Native)
Parent Process: launchd [94]

Date/Time: 2010-03-05 23:59:32.209 +0300
OS Version: Mac OS X 10.5.6 (9G66)
Report Version: 6

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Crashed Thread: 0

Thread 0 Crashed:
0 libSystem.B.dylib 0x95e41e42 __kill + 10
1 libSystem.B.dylib 0x95eb423a raise + 26
2 libSystem.B.dylib 0x95ec0679 abort + 73
3 libstdc++.6.dylib 0x9521c005 0x951d4000 + 294917
4 libstdc++.6.dylib 0x9521a10c __gxx_personality_v0 + 1108
5 libstdc++.6.dylib 0x9521a14b std::terminate() + 29
6 libstdc++.6.dylib 0x9521a261 __cxa_throw + 101
7 …gn.framework.CoreFoundation 0x00559883 Sys_MachExceptionHandler::Init() + 1951
8 com.apple.QD 0x95ae5d0f SetOrigin + 101
9 com.digidesign.framework.DFW 0x00a36f67 DFW_Painter_ForwardDeclarationHack::TrackLeakEntry(DFW_Painter*, bool, void const*) + 217
10 com.digidesign.framework.DFW 0x009dfc10 DFW_PainterQD::GetOrigin() + 58
11 …gidesign.framework.ProTools 0x01feeeb1 0x1bbc000 + 4402865
12 …gidesign.framework.ProTools 0x01fef15f 0x1bbc000 + 4403551
13 …gidesign.framework.ProTools 0x021747b7 0x1bbc000 + 5998519
14 …gidesign.framework.ProTools 0x02518257 0x1bbc000 + 9814615
15 …gidesign.framework.ProTools 0x0251832d 0x1bbc000 + 9814829
16 …gidesign.framework.ProTools 0x026bb779 0x1bbc000 + 11532153
17 com.digidesign.framework.DFW 0x009f31e5 DFW_Timers::LockedCallbackTimerProc::operator()(void*) + 55
18 com.digidesign.framework.DFW 0x009f1995 DFW_Timers::CallbackTimerManager::MasterCallback(void*) + 77
19 com.digidesign.framework.DFW 0x009f0ce5 DFW_EventListener::NotifyListeners(std::list<DFW_EventListener*, std::allocator<DFW_EventListener*> >&, DFW_EventListener::NotificationType, DFW_EventRef, DFW_EventTarget*) + 3419
20 com.digidesign.framework.DFW 0x00aac7b2 DFW_EventLoop::RunningLegacyEventLoop() + 846
21 com.apple.CoreFoundation 0x96e5eb25 CFRunLoopRunSpecific + 4469
22 com.apple.CoreFoundation 0x96e5ecd8 CFRunLoopRunInMode + 88
23 com. MyPlug19954 0x1b83af74 juce::MessageManager::runDispatchLoopUntil(int) + 388
24 com. MyPlug19954 0x1b91fa24 removeSubWindow(void*, juce::Component*) + 308
25 com. MyPlug19954 0x1b92031a JucePlugInProcess::JuceCustomUIView::EditorCompWrapper::~EditorCompWrapper() + 58
26 com. MyPlug19954 0x1b92137c JucePlugInProcess::SetViewPort(OpaqueGrafPtr*) + 908
27 com. MyPlug19954 0x1b9a2ea2 CProcessType::SetViewPort(long, OpaqueGrafPtr*) + 50
28 com. MyPlug19954 0x1b91f350 S3ArgGroupFunc<unsigned long, long, OpaqueGrafPtr*>::operator()() + 80
29 com. MyPlug19954 0x1b9a3a33 CallAndTranslateExceptionsToReturnValues(SGenFuncRetLong*) + 19
30 com. MyPlug19954 0x1b918dd9 CallNoThrowCommon(SGenFuncRetLong*, unsigned char, unsigned char) + 89
31 com. MyPlug19954 0x1b91b085 PI_SetViewPort(unsigned long, long, OpaqueGrafPtr*) + 85
32 com.digidesign.framework.DAE 0x03e2a2bb FicGetApplicationInterface + 92763
33 com.digidesign.framework.DAE 0x03eef905 FicSetPlugInPort + 41
34 …gidesign.framework.ProTools 0x01feeceb 0x1bbc000 + 4402411
35 …gidesign.framework.ProTools 0x0217405c 0x1bbc000 + 5996636
36 …gidesign.framework.ProTools 0x0217633b 0x1bbc000 + 6005563
37 …gidesign.framework.ProTools 0x0217708a 0x1bbc000 + 6008970
38 …gidesign.framework.ProTools 0x021772e6 0x1bbc000 + 6009574
39 com.digidesign.framework.DFW 0x00974b8d TWindow::CloseAndFree() + 21
40 …gidesign.framework.ProTools 0x02031efd 0x1bbc000 + 4677373
41 com.digidesign.framework.DFW 0x00983b4b TView::HandleMouseDown(VPoint const&, TToolboxEvent*, _CPoint) + 703
42 com.digidesign.framework.DFW 0x00983953 TView::HandleMouseDown(VPoint const&, TToolboxEvent*, _CPoint) + 199
43 com.digidesign.framework.DFW 0x00983953 TView::HandleMouseDown(VPoint const&, TToolboxEvent*, _CPoint) + 199
44 com.digidesign.framework.DFW 0x00983953 TView::HandleMouseDown(VPoint const&, TToolboxEvent*, _CPoint) + 199
45 com.digidesign.framework.DFW 0x00983953 TView::HandleMouseDown(VPoint const&, TToolboxEvent*, _CPoint) + 199
46 com.digidesign.framework.DFW 0x00983953 TView::HandleMouseDown(VPoint const&, TToolboxEvent*, _CPoint) + 199
47 com.digidesign.framework.DFW 0x00983953 TView::HandleMouseDown(VPoint const&, TToolboxEvent*, _CPoint) + 199
48 com.digidesign.framework.DFW 0x00983953 TView::HandleMouseDown(VPoint const&, TToolboxEvent*, _CPoint) + 199
49 com.digidesign.framework.DFW 0x0097598e TWindow::HandleMouseDown(VPoint const&, TToolboxEvent*, _CPoint) + 168
50 com.digidesign.framework.DFW 0x00a49ae1 DFW_PainterOpenGL::SetPenMode(EPenMode) + 19745
51 com.apple.AppKit 0x93d431a3 -[NSWindow sendEvent:] + 5381
52 com.apple.AppKit 0x942bad13 carbonAppWindowMouseHandler + 269
53 com.apple.AppKit 0x93fa57a5 carbonAppWindowHandler + 120
54 com.apple.HIToolbox 0x93448143 DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 1181
55 com.apple.HIToolbox 0x9344757d SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 405
56 com.apple.HIToolbox 0x93463ed2 SendEventToEventTarget + 52
57 com.apple.HIToolbox 0x934760a8 ToolboxEventDispatcherHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) + 1208
58 com.apple.HIToolbox 0x934484fc DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 2134
59 com.apple.HIToolbox 0x9344757d SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 405
60 com.apple.HIToolbox 0x93463ed2 SendEventToEventTarget + 52
61 com.apple.HIToolbox 0x934d0b80 ToolboxEventDispatcher + 86
62 com.apple.HIToolbox 0x934cd3da RunApplicationEventLoop + 222
63 com.digidesign.framework.DFW 0x00aac317 DFW_EventLoop::RunApplicationEventLoop() + 11
64 com.digidesign.framework.DFW 0x0099e487 TApplication::Run() + 45
65 …gidesign.framework.ProTools 0x027fe54c LaunchProTools + 1560
66 com.digidesign.ProToolsLE 0x0000a2a9 0x1000 + 37545
67 com.digidesign.ProToolsLE 0x0000ab38 0x1000 + 39736
68 com.digidesign.ProToolsLE 0x00004f4f 0x1000 + 16207
69 com.digidesign.ProToolsLE 0x00004e7d 0x1000 + 15997

Tricky. The runDispatchLoopUntil is needed to allow OSX to clear up the window before giving control back to PT, but it does risk allowing PT to do something to the plugin while its in the middle of shutting it down, and it seems like you’ve found a way to trigger that. I’m a bit stumped as to what a better solution would be, though…

I’m sorry for escalating it again, but could you please give me some help with this crash… I’m a windows developer, so debugging with xcode &macos is a pain…

I really can’t think of anything else to suggest, I’m afraid…

i’m getting crashes in Live too, but not in the plugin code but in Live. It happens when a plugin is loaded and you try doing File->New Project in Live, it crashes (almost always), i tried debugging it but got only asm garbage from Live, all JUCE-based code completed without any problems, it’s Live that’s crashing.

BTW, it looks like it is not PT sending something to plugin while UI is opening/closing fast.
I’ve done a fast hack :

class editor  : public AudioProcessorEditor,
                public ChangeListener,
                public SliderListener,
                public ButtonListener
	    public Timer
{
public:
    editor (Filter* const Filter);
    ~editor();

    friend class Filter;
    bool isAlive;
    void timerCallback() {isAlive = true;}
....
...
}

editor::editor (Filter* const Filter)
{
...
..
isAlive = false;
startTimer(1000);
}

void editor::sliderValueChanged(...)
{
 if (!isAlive) return;

..
...
..
}

so, value changes are ignored while UI is “warming up”. I’ve got uninitialized knobs states but crash is gone and all is working nice.
This is ugly solution I know, but may be it will help somehow…

Sorry, I’ve made a wrong statement. This “update” just made the crash less frequent =(

Just in case if someone will have the same problem, here is my workarownd.
It is not an elegant solution, but works for me.
I’ve added a parameter (wit hdefault value) to runDispatchLoopUntil (int millisecondsToRunFor, int doNotDeliver /* = 0 */ )
and in mac version of MessageManager I added doNotDeliver parameter check so it will disable message delivering If I need:

 if ( doNotDeliver == 0 && e != 0 && ! isEventBlockedByModalComps (e))
            [NSApp sendEvent: e];

now, in
juce_RTAS_MacUtilities.mm
void removeSubWindow (void* nsWindow, Component* comp)

I call runDispatchLoopUntil() with doNotDeliver parameter enabled, so It parses message queue but does not call plugin UI

So all is working fine now =)
Hope this will help, and sorry for my English =)

Surely there’s no need to hack the messagemanager to do that, you could have just done this:

[code]void removeSubWindow (void* nsWindow, Component* comp)
{
…etc…

for (int i = 20; --i >= 0;)
    CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.001, true);

}[/code]

But I’m pretty sure I tried doing exactly that, and it didn’t work. The dispatch loop runs there to make sure that the window gets a chance to fully delete itself before control returns to PT, because otherwise it caused the shutdown crash. Are you sure that with this, it doesn’t crash if you shut down with the plugin UI open?

Sorry, can’t say it for sure now, will try it today.

Hi,
Just tried to close PT LE 8 with opened pkugin UI, and it is ok here.

I’m not a cocoa guru (just googled about it for 2 hours or so ), but my hack is actually dequeing messagews from the message queue, so may be it is the difference (compared to your suggestion)?

Hmm, yes, looking again at your code I hadn’t noticed that it was also dequeueing. Yes, that could be the difference.

It’d be much better to keep the fix within the RTAS code, so If this works:

[code]void removeSubWindow (void* nsWindow, Component* comp)
{

for (int i = 20; --i >= 0;)
{
    const ScopedAutoReleasePool pool;
    CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.001, true);

    NSEvent* e = [NSApp nextEventMatchingMask: NSAnyEventMask
                                    untilDate: [NSDate dateWithTimeIntervalSinceNow: 0.001]
                                       inMode: NSDefaultRunLoopMode
                                      dequeue: YES];
}

}
[/code]

…then I’d be quite happy with that!

Tried it, and found that all this is not the real solution =)
Your code works, but I found that if I have 1 plugin for example (I mean one my plugin instantiated in project), it still crashes. Lowering i value (cycle counter) to 5, fixed the crash, but it started crashing with 5 plugins loaded =)
So it is a temporary solution, and I hope that someone with cocoa knowlege and pt le 8 installed will figure this problem out…

Hello Bunker,

Currently firing again xcode since a while … and I also experiment this crash with juceDemoPlugin, when opening/closing UI fast (i.e; double-triple clicking on the insert)
Do your hack still work ? No hidden issue found ?

Jules any other suggestions ?

best,

Salvator

No, my hack just made the crash not so frequent =(

Hi, as far as I understand - this bug will never (in near future) will be addressed.
I paid money for JUCE, and it is crashing, I can’t release plugin with crash, it is just not acceptible.

So, If anyone have the knowledge and time to fix this crash, please contact me via PM. I would like to find someone how will fix this for me, for money of course.

Sorry for going with this on public, but I’m a windows developer, and bought JUCE to be able to develop stable, cross platform plugins without diving in mac osx guts.

Thanks!