Application: prevent crash on startup when "Interface Crashed" dialog is shown.

If the application "Interface Crashed" dialog is shown at startup, it can cause Application to receive events before it has been fully constructed.
In this case the QMainWindow _window pointer is uninitialized, causing Menu::getInstance() to de-reference an invalid pointer.

The fix for this is three fold.

1. Construct the QMainWindow before calling setupEssentials (which in turn spawns the "Interface Crashed" dialog).
2. Change Menu::getInstance() from a static_cast to a dynamic_cast.  This will cause it to return a nullptr if [QMainWindow::menuBar()](http://doc.qt.io/qt-4.8/qmainwindow.html#menuBar) returns an instance of QMenuBar and not a ui::Menu instance.
3. In Application::event return false if Menu::getInstance() returns a nullptr.  This should prevent any code that relies on having a valid ui::Menu instance from running.
This commit is contained in:
Anthony J. Thibault 2016-03-16 18:03:59 -07:00
parent 35aa074955
commit a8bc8a7843
3 changed files with 9 additions and 4 deletions

View file

@ -452,8 +452,8 @@ Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context);
Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
QApplication(argc, argv),
_dependencyManagerIsSetup(setupEssentials(argc, argv)),
_window(new MainWindow(desktop())),
_dependencyManagerIsSetup(setupEssentials(argc, argv)),
_undoStackScriptingInterface(&_undoStack),
_frameCount(0),
_fps(60.0f),
@ -1744,6 +1744,11 @@ bool Application::importSVOFromURL(const QString& urlString) {
}
bool Application::event(QEvent* event) {
if (!Menu::getInstance()) {
return false;
}
if ((int)event->type() == (int)Lambda) {
((LambdaEvent*)event)->call();
return true;

View file

@ -381,6 +381,8 @@ private:
void maybeToggleMenuVisible(QMouseEvent* event);
MainWindow* _window;
bool _dependencyManagerIsSetup;
OffscreenGLCanvas* _offscreenContext { nullptr };
@ -390,8 +392,6 @@ private:
bool _activatingDisplayPlugin { false };
QMap<gpu::TexturePointer, gpu::FramebufferPointer> _lockedFramebufferMap;
MainWindow* _window;
QUndoStack _undoStack;
UndoStackScriptingInterface _undoStackScriptingInterface;

View file

@ -46,7 +46,7 @@
#include "Menu.h"
Menu* Menu::getInstance() {
return static_cast<Menu*>(qApp->getWindow()->menuBar());
return dynamic_cast<Menu*>(qApp->getWindow()->menuBar());
}
Menu::Menu() {