Segfault during first window constructors on OS X Lion.
-
I have a Qt application running in Linux and am trying to get running on OS X again. I previously had it running on 10.6 with Qt 4.7.0, but am now trying with Qt 4.8 and on OS X 10.7. The program works perfectly on linux, but am having a consistent problem when trying to construct the first QWidget.
The way the program is designed is a QApplication is created, another thread ( posix, not Qt ) is created and run, and then the main thread goes into the qApp::exec() loop. The second thread then gets messages and starts various components of the program, one of the eventually will be to open a QGLWidget. This widget is started by passing a custom event to the Qt thread. Any ideas or help will be greatly appreciated...
During this stage on OS X I get a segfault and get the following stderr:
@QObject::setParent: Cannot set parent, new parent is in a different thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
Segmentation fault: 11 (core dumped)
@The backtrace from apples report is as follows:
@Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 QtGui 0x000000010d049e78 QPixmap::isQBitmap() const + 8
1 QtGui 0x000000010d0a67ff QBrush::isOpaque() const + 447
2 QtGui 0x000000010d000e56 QWidgetPrivate::init(QWidget*, QFlagsQt::WindowType) + 718
3 QtGui 0x000000010d001042 QWidget::QWidget(QWidgetPrivate&, QWidget*, QFlagsQt::WindowType) + 86
4 QtOpenGL 0x000000010db4ede9 QGLWidget::QGLWidget(QGLFormat const&, QWidget*, QGLWidget const*, QFlagsQt::WindowType) + 79
5 MediaEngine 0x000000010bac3d88 BaseWindow::BaseWindow() + 172
6 MediaEngine 0x000000010bacf756 VideoWindow::VideoWindow() + 24
7 MediaEngine 0x000000010baac90b GuiManager2::CreateGlWindow(WindowConfig) + 401
8 MediaEngine 0x000000010bab01c2 GuiManager2::customEvent(QEvent*) + 528
9 QtCore 0x000000010ccae29d QObject::event(QEvent*) + 1191
10 QtGui 0x000000010cfaf308 QApplicationPrivate::notify_helper(QObject*, QEvent*) + 304
11 QtGui 0x000000010cfaf589 QApplication::notify(QObject*, QEvent*) + 603
12 QtCore 0x000000010cc9a156 QCoreApplication::notifyInternal(QObject*, QEvent*) + 104
13 QtCore 0x000000010cc9a543 QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) + 557
14 com.apple.CoreFoundation 0x00007fff88c356e1 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
15 com.apple.CoreFoundation 0x00007fff88c34f4d __CFRunLoopDoSources0 + 253
16 com.apple.CoreFoundation 0x00007fff88c5bd39 __CFRunLoopRun + 905
17 com.apple.CoreFoundation 0x00007fff88c5b676 CFRunLoopRunSpecific + 230
18 com.apple.HIToolbox 0x00007fff8cb1b31f RunCurrentEventLoopInMode + 277
19 com.apple.HIToolbox 0x00007fff8cb225c9 ReceiveNextEventCommon + 355
20 com.apple.HIToolbox 0x00007fff8cb22456 BlockUntilNextEventMatchingListInMode + 62
21 com.apple.AppKit 0x00007fff86e04f5d _DPSNextEvent + 659
22 com.apple.AppKit 0x00007fff86e04861 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135
23 com.apple.AppKit 0x00007fff86e0119d -[NSApplication run] + 470
24 QtGui 0x000000010cf6b090 QEventDispatcherMac::processEvents(QFlagsQEventLoop::ProcessEventsFlag) + 840
25 QtCore 0x000000010cc97718 QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag) + 394
26 QtCore 0x000000010cc9a88b QCoreApplication::exec() + 175
27 MediaEngine 0x000000010bc65c68 MagorQtApp::MainRun() + 616
28 MediaEngine 0x000000010b972009 MediaAdmin::Run(int&, char**) + 143 (MediaAdmin.cpp:82)
29 MediaEngine 0x000000010b9a9056 main + 294 (main.cpp:46)
30 MediaEngine 0x000000010b9667a4 start + 52
@ -
Ya, that's what confuses me too. The object is a QGLWidget, it is constructed on the main thread ( as you can see in the backtrace ), and there is no parent. The only QObject created on a different thread than the main is the QEvent subclass to pass event to the GuiManager2.
GuiManager2 is a QObject created on the stack on the main thread before QApp->exec(). Posting event from 2nd thread to main thread:
@QApplication::postEvent((QObject*)this, new CustomQtStartEvent(winConfig));
@Handling this customEvent is where we construct the new window:
@void GuiManager2::customEvent(QEvent *event)
{
if(event->type() == (QEvent::Type)CUSTOM_NEW_WINDOW)
{
mpTempGlWindow = new VideoWindow();
int result = mpTempGlWindow->Initialize(config);
...
}
}
@Constructor for the QGLWidget:
@
BaseWindow::BaseWindow():
QGLWidget(QGLFormat(QGL::DoubleBuffer)),
@From the constructor, the *parent is passed as 0 so we shouldn't even have a parent for this window. Inside the QGLWidget itself all it's classes should be properly parented to it correct?
-
Still hard to say what's going on here. The only thing that's clear is that a second thread entered the game at the wrong point. I would always trust Qt here instead of a programmer's assertion.
Best thing would be to boil down your app to a small test case that does nothing more than reproduce the error. Chances are good that you find the mistake on the way.
-
Hi guys!
I'm having exactly the same problem.I'm running OSX Mountain Lion and Qt 4.8.3, and I have had to compile Qt SQL plugin myself. The code is so simple:
@#include "QMainWindowEPGEditor.h"#include "QSqlDatabase.h"
#include "QMessageBox.h"
#include "QSqlError.h"
#include "QSqlQuery.h"
#include "QDebug.h"QMainWindowEPGEditor::QMainWindowEPGEditor(): QMainWindow()
{
ui.setupUi(this);
this->initialize();
}QMainWindowEPGEditor::~QMainWindowEPGEditor()
{
}void QMainWindowEPGEditor::initialize()
{
this->openDatabase();
this->queryData();
this->closeDatabase();
}void QMainWindowEPGEditor::openDatabase()
{
mDatabase = QSqlDatabase::addDatabase("QMYSQL");
mDatabase.setHostName("XXXXX");
mDatabase.setPort(XXXX);
mDatabase.setDatabaseName("XXXX");
mDatabase.setUserName("XXXXXX");
mDatabase.setPassword("XXXXXXX");
if (!mDatabase.open())
{
QMessageBox::critical(0, QObject::tr("Database Error"), mDatabase.lastError().text());
}
}void QMainWindowEPGEditor::queryData()
{
QSqlQuery query;
query.exec("SELECT * FROM XXXX");
while (query.next())
{
QString channelName = query.value(1).toString();
ui.listWidgetChannels->addItem(channelName);
}
}void QMainWindowEPGEditor::closeDatabase()
{
mDatabase.close();
}
@So, when I remove the code related with database there is no warning messages, and no crash. But if I put just the line
@
mDatabase = QSqlDatabase::addDatabase("QMYSQL");
@
without the rest of the code, the application crashes when I call show() method on the QMainWindowEPGEditor, and the warning messages are shown.As you can see, I'm not using multithreading myself. Maybe libqsqlmysql is using...
I have spent a lot of hours trying to figure this out,
Ideas?Thanks in advance,
Robert. -