Standalone app crash at startup due to mouse movements over dialog box?


#1

Since a relatively recent update of the JUCE version we're using, our applicatin crashes at startup.
At the startup of our (standalone) application, we launch a dialog box that asks the user to enter software activation credentials.
In debug mode, this is all still fine, but in release mode, a crash occurs as soon as you move the mouse over the dialog box.

Stack trace:

MyApplication.exe!juce::MouseInputSourceInternal::sendMouseEnter(juce::Component & comp, juce::Point<float> screenPos, juce::Time time)  Line 120    C++
MyApplication.exe!juce::MouseInputSourceInternal::setComponentUnderMouse(juce::Component * const newComponent, juce::Point<float> screenPos, juce::Time time)  Line 244    C++
MyApplication.exe!juce::MouseInputSourceInternal::setScreenPos(juce::Point<float> newScreenPos, juce::Time time, const bool forceUpdate)  Line 266    C++
MyApplication.exe!juce::MouseInputSourceInternal::handleEvent(juce::ComponentPeer & newPeer, juce::Point<float> positionWithinPeer, juce::Time time, juce::ModifierKeys newMods, float newPressure)  Line 320    C++
MyApplication.exe!juce::MouseInputSource::handleEvent(juce::ComponentPeer & peer, juce::Point<float> pos, __int64 time, juce::ModifierKeys mods, float pressure)  Line 582    C++
MyApplication.exe!juce::ComponentPeer::handleMouseEvent(int touchIndex, juce::Point<float> pos, juce::ModifierKeys newMods, float newPressure, __int64 time)  Line 92    C++
MyApplication.exe!juce::HWNDComponentPeer::doMouseEvent(juce::Point<float> position, float pressure)  Line 1669    C++
MyApplication.exe!juce::HWNDComponentPeer::doMouseMove(juce::Point<float> position)  Line 1765    C++
MyApplication.exe!juce::HWNDComponentPeer::peerWindowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam)  Line 2453 + 0x29 bytes    C++
user32.dll!750662fa()     
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]    
user32.dll!75066d3a()     
user32.dll!75066ce9()     
user32.dll!750677d3()     
user32.dll!7506789a()     
MyApplication.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(const bool returnIfNoPendingMessages)  Line 143    C++
MyApplication.exe!juce::MessageManager::runDispatchLoopUntil(int millisecondsToRunFor)  Line 94 + 0x10 bytes    C++
MyApplication.exe!juce::ModalComponentManager::runEventLoopForCurrentComponent()  Line 285 + 0xd bytes    C++
MyApplication.exe!juce::Component::runModalLoop()  Line 1712    C++
MyApplication.exe!MyApplication::initialise(const juce::String & commandLine)  Line 84    C++
MyApplication.exe!juce::JUCEApplicationBase::initialiseApp()  Line 261 + 0x15 bytes    C++
MyApplication.exe!juce::JUCEApplication::initialiseApp()  Line 88 + 0x5 bytes    C++
MyApplication.exe!juce::JUCEApplicationBase::main()  Line 234 + 0x7 bytes    C++
MyApplication.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, HINSTANCE__ * __formal, HINSTANCE__ * __formal)  Line 262 + 0xf bytes    C++
MyApplication.exe!__tmainCRTStartup()  Line 275 + 0x1c bytes    C
kernel32.dll!755b337a()     
ntdll.dll!76f19882()     
ntdll.dll!76f19855()     

Seems like the mouse handling now ends up in a problematic situation.

Now, in our Main.cpp file, the main application class MyApplication : public JUCEApplication is defined and its initialise goes as follows:


void initialise (const String& commandLine)
{
    ...
    if (!m_ActivationModel.IsActivated())
    {
        DialogWindow::LaunchOptions dialog;
        dialog.componentToCentreAround = nullptr;
        dialog.content.set(new InitialActivationDialogComponent(&m_ActivationController, &m_UpdateCheckerController), true);
        dialog.dialogTitle = "Application activation";
        dialog.useNativeTitleBar = true;
        dialog.runModal();
    }
    if (m_ActivationModel.IsActivated())
    {
        ...
        mainWindow = new MainAppWindow(...);
        ...
    }
    else
    {
        quit();
    }
}

Is the modal dialog box now a problem at the start of the program?
And if so, any suggestions as to how to restructure this without a modal dialog box, in a way that I can still prevent the application from continuing with its main functionality until the activation was performed?

This is with a very recent Juce version (of 2015-12-11, somewhere after 4.0.2). I know I should always use the latest JUCE version, but I suspect that may not be the issue here, and switching to the tip now will lead to all sorts of other incompatibilities I'll need to go through first. But if really necessary, I will do that first...


#2

Modal loops are always a terrible idea and can cause horrible problems. Generally this is because if you try to quit or delete some vital object while it's running, there's a whole bunch of stuff on the stack that can blow up when the stack unwinds.

So running a modal loop in the app's initialisation is a particularly bad place to do it! There's really no reason at all to do it the way you've written it - you can easily launch the box in an asynchronous modal state, and have callbacks to safely handle it being closed.

That being said, I've no idea what's going on in this particular case, except that it looks like a dangling pointer to some component. If you have different results in debug/release, then it could be an uninitialised variable somewhere in your code.


#3

[once again, I didn't get any notification about a reply to this topic, although I am subscribed...]

 

OK, thanks Jules. I'll look into using callbacks.

This probably also means that some of the code in the DialogsDemo.cpp needs to be updated, as there it looks like modal loops are being used there (for example for the "extraComponentsAlertWindow" case).