Please nominate your Qt Champions for 2021! https://forum.qt.io/topic/132134/looking-for-the-2021-qt-champions

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
    @



  • Hard to judge without any code.

    But the error message is quite clear: You try to set a parent in one thread to a QObject created in another thread. That doesn't work.



  • 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.



  • I have found something out.
    If I switch from
    @
    mDatabase = QSqlDatabase::addDatabase("QMYSQL");
    @
    to
    @
    mDatabase = QSqlDatabase::addDatabase("QSQLITE");
    @
    There is no crash or warning messages. So there has to be something with mysql plugin. Right?


Log in to reply