Integrating QML with existing OGL program crashes on Windows
-
Hi, I've been working on a project for a couple of months and during most of the development I used ImGui for the UI, and while it's nice for testing during the development it doesn't really cut it as a general GUI system.
I figured I could try and give QML a spin because it's probably one of the most powerful UI frameworks out there, and after digging for a bit I found OpenAge which uses SDL and QML so at that point I was confident enough that it should also work with SFML. After working on it for some time, while using OpenAge and Qt docs as references, I managed to get the integration up and running.Then I switched to Windows and everything went downhill. I connect to QQmlComponent::statusChanged signal and wait until it's ready, where I call QQmlComponent::create function which segfaults on Windows.
I'm not that familiar with Qt Creator and its debugger UI but from what I could gather it's a Text element that I put on top of a custom Button component that crashes, something related to the Text Engine and Font Database. Further down the stack it crashes in DirectWrite related functions in Dwrite.dll, however I'm not sure whether that's the cause or it's just a side effect of the issue up the stack.
Oddly enough compiling the program in Debug mode without the debugger attached makes it work, however the moment I run it through the debugger, or in Release mode, it crashes instantly.I ran into two bugs on the issue tracker with similar stack trace (albeit not the same), namely QTBUG-44708 and QTBUG-49860 which were both supposedly fixed in Qt 5.5.x so I'm not sure whether the bug started manifesting itself again or it's a completely unrelated issue with similar underlying cause.
Removing the Text element from my Button component makes the application run in Release mode until I hover any element and doesn't crash when running in Release with a debugger. In Debug mode it works fine regardless of the presence of debugger. That makes me even more confused because I'm now not even sure whether it's related to the Text Engine and Font Database or not.
I also found the following information in Qt docs:
QQuickRenderControl depends on OpenGL to function and will not function with Qt Quick 2D Renderer. Using QQuickRenderControl can lead to unexpected behavior and crashes.
But I don't think I'm using the software renderer unless it's the default (but I couldn't find a way to verify it).
Some other details in case they are important.
The project works fine, both in Debug and Release mode, when built on Linux 64-bit (Kernel 4.12) using GCC 7.1.1 with SFML 2.4.2 and Qt5 5.9.1.
The project crashes, in Release or in Debug (when the debugger is attached), when built on Windows 7 SP1 64-bit using MSVS 2017 (vc 14.1) with SFML 2.4.2 and Qt5 5.9.1, I also tried downgrading to Qt 5.9.0 just to see if it's a library related bug but no dice.Any help in diagnosing the issue and/or pointing me in the right direction would be greatly appreciated.
The code is too long to post here so I've zipped it and uploaded to a file sharing service (as I lack the privileges to upload attachments here): https://a.pomf.cat/jsftxc.zip
It requires Qt 5 and SFML to build. -
I've been digging around for the last couple of days trying to find the root cause of the issue and then it turned out that even the simplest Qt Quick application will crash with the same stack trace as long as it displays some text. Likewise none of the examples that are shipped with Qt (accessible through the Welcome -> Examples screen in Qt Creator) work, they simply crash on startup.
Would it be safe to assume it's a bug with Qt 5.9.1 built using MSVS 2017 (VC14.1)?
How do I even proceed now? Do I report it on the issue tracker?Here's the relevant backtrace:
. 0 Id: 24f8.dac Suspend: 1 Teb: 000007ff`fffde000 Unfrozen Child-SP RetAddr Call Site 00000000`0029df90 000007fe`ff58ab87 KERNELBASE!RaiseException+0x3d 00000000`0029e060 000007fe`ec6a865d msvcrt!CxxThrowException+0x87 00000000`0029e0d0 000007fe`e658ef00 dwrite!DWriteCreateFactory+0x3f51 00000000`0029e150 000007fe`e658fecb qwindowsd!createDirectWriteFactory(struct IDWriteFactory ** factory = 0x00000000`040a7428)+0x90 [c:\users\qt\work\qt\qtbase\src\platformsupport\fontdatabases\windows\qwindowsfontdatabase.cpp @ 103] 00000000`0029e190 000007fe`e658ce92 qwindowsd!initDirectWrite(class QWindowsFontEngineData * d = 0x00000000`040a7010)+0x2b [c:\users\qt\work\qt\qtbase\src\platformsupport\fontdatabases\windows\qwindowsfontdatabase.cpp @ 653] 00000000`0029e1e0 000007fe`e658b060 qwindowsd!QWindowsFontDatabase::createEngine(struct QFontDef * request = 0x00000000`0029e760, class QString * faceName = 0x00000000`0029e640, int dpi = 96, class QSharedPointer<QWindowsFontEngineData> * data = 0x00000000`0029e678)+0x1d2 [c:\users\qt\work\qt\qtbase\src\platformsupport\fontdatabases\windows\qwindowsfontdatabase.cpp @ 1888] 00000000`0029e600 000007fe`e6d4dedc qwindowsd!QWindowsFontDatabase::fontEngine(struct QFontDef * fontDef = 0x00000000`0029e760, void * handle = 0x00000000`00000000)+0x60 [c:\users\qt\work\qt\qtbase\src\platformsupport\fontdatabases\windows\qwindowsfontdatabase.cpp @ 1247] 00000000`0029e6c0 000007fe`e6d4e0f8 Qt5Guid!loadSingleEngine(int script = 2, struct QFontDef * request = 0x00000000`0029eba0, struct QtFontFamily * family = 0x00000000`04117820, struct QtFontFoundry * foundry = 0x00000000`0411b790, struct QtFontStyle * style = 0x00000000`0411b8c0, struct QtFontSize * size = 0x00000000`0411b950)+0x3dc [c:\users\qt\work\qt\qtbase\src\gui\text\qfontdatabase.cpp @ 971] 00000000`0029e820 000007fe`e6d49704 Qt5Guid!loadEngine(int script = 2, struct QFontDef * request = 0x00000000`0029eba0, struct QtFontFamily * family = 0x00000000`04117820, struct QtFontFoundry * foundry = 0x00000000`0411b790, struct QtFontStyle * style = 0x00000000`0411b8c0, struct QtFontSize * size = 0x00000000`0411b950)+0x58 [c:\users\qt\work\qt\qtbase\src\gui\text\qfontdatabase.cpp @ 1000] 00000000`0029e8d0 000007fe`e6d49fd1 Qt5Guid!QFontDatabase::findFont(struct QFontDef * request = 0x00000000`0029eba0, int script = 2)+0x2e4 [c:\users\qt\work\qt\qtbase\src\gui\text\qfontdatabase.cpp @ 2686] 00000000`0029eb60 000007fe`e6d0be28 Qt5Guid!QFontDatabase::load(class QFontPrivate * d = 0x00000000`040a3960, int script = 2)+0x3c1 [c:\users\qt\work\qt\qtbase\src\gui\text\qfontdatabase.cpp @ 2803] 00000000`0029ec60 000007fe`e6d0ae88 Qt5Guid!QFontPrivate::engineForScript(int script = 2)+0xf8 [c:\users\qt\work\qt\qtbase\src\gui\text\qfont.cpp @ 218] 00000000`0029ecc0 000007fe`e8961328 Qt5Guid!QFontInfo::family(void)+0x28 [c:\users\qt\work\qt\qtbase\src\gui\text\qfont.cpp @ 2456] 00000000`0029ed00 000007fe`e8962424 qtquickcontrols2materialstyleplugind!QQuickMaterialTheme::QQuickMaterialTheme(class QPlatformTheme * theme = 0x00000000`00000000)+0x148 [c:\users\qt\work\qt\qtquickcontrols2\src\imports\controls\material\qquickmaterialtheme.cpp @ 50] 00000000`0029ee20 000007fe`f62e30f6 qtquickcontrols2materialstyleplugind!QtQuickControls2MaterialStylePlugin::createTheme(void)+0x24 [c:\users\qt\work\qt\qtquickcontrols2\src\imports\controls\material\qtquickcontrols2materialstyleplugin.cpp @ 115] 00000000`0029ee60 000007fe`e8961d40 Qt5QuickControls2d!QQuickStylePlugin::initializeEngine(class QQmlEngine * engine = 0x00000000`0029f590, char * uri = 0x00000000`040a35b8 "QtQuick.Controls.Material")+0xf6 [c:\users\qt\work\qt\qtquickcontrols2\src\quickcontrols2\qquickstyleplugin.cpp @ 70] 00000000`0029eec0 00000000`65d9ce00 qtquickcontrols2materialstyleplugind!QtQuickControls2MaterialStylePlugin::initializeEngine(class QQmlEngine * engine = 0x00000000`0029f590, char * uri = 0x00000000`040a35b8 "QtQuick.Controls.Material")+0x40 [c:\users\qt\work\qt\qtquickcontrols2\src\imports\controls\material\qtquickcontrols2materialstyleplugin.cpp @ 89] 00000000`0029f010 00000000`65db3737 Qt5Qmld!QQmlTypeLoaderThread::initializeEngineMain(class QQmlExtensionInterface * iface = 0x00000000`040a00e0, char * uri = 0x00000000`040a35b8 "QtQuick.Controls.Material")+0xa0 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 916] 00000000`0029f060 00000000`65e61fb2 Qt5Qmld!`QQmlThread::callMethodInMain<QQmlExtensionInterface * __ptr64,char const * __ptr64,QQmlExtensionInterface * __ptr64,char const * __ptr64,QQmlTypeLoaderThread>'::`2'::I::call(class QQmlThread * thread = 0x00000000`00356790)+0x37 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\ftw\qqmlthread_p.h @ 224] 00000000`0029f0a0 00000000`65da6865 Qt5Qmld!QQmlThread::internalCallMethodInThread(struct QQmlThread::Message * message = 0x00000000`01ca50f0)+0x162 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\ftw\qqmlthread.cpp @ 322] 1 Id: 24f8.201c Suspend: 1 Teb: 000007ff`fffdc000 Unfrozen "QQmlThread" Child-SP RetAddr Call Site 00000000`0253aeb8 000007fe`fd5f10dc ntdll!NtWaitForSingleObject+0xa 00000000`0253aec0 00000000`665d372e KERNELBASE!WaitForSingleObjectEx+0x9c 00000000`0253af60 00000000`665d3307 Qt5Cored!QWaitConditionPrivate::wait(class QWaitConditionEvent * wce = 0x00000000`04072c90, unsigned long time = 0xffffffff)+0x2e [c:\users\qt\work\qt\qtbase\src\corelib\thread\qwaitcondition_win.cpp @ 118] 00000000`0253afa0 00000000`65e635fa Qt5Cored!QWaitCondition::wait(class QMutex * mutex = 0x00000000`0034fd00, unsigned long time = 0xffffffff)+0x97 [c:\users\qt\work\qt\qtbase\src\corelib\thread\qwaitcondition_win.cpp @ 179] 00000000`0253b000 00000000`65e6221f Qt5Qmld!QQmlThreadPrivate::wait(void)+0x2a [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\ftw\qqmlthread.cpp @ 62] 00000000`0253b030 00000000`65da67ef Qt5Qmld!QQmlThread::internalCallMethodInMain(struct QQmlThread::Message * message = 0x00000000`040a3650)+0x18f [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\ftw\qqmlthread.cpp @ 359] 00000000`0253b080 00000000`65d9cb1e Qt5Qmld!QQmlThread::callMethodInMain<QQmlExtensionInterface * __ptr64,char const * __ptr64,QQmlExtensionInterface * __ptr64,char const * __ptr64,QQmlTypeLoaderThread>(<function> * Member = 0x00000000`6592115c, class QQmlExtensionInterface ** arg = 0x00000000`0253b0f8, char ** arg2 = 0x00000000`0253b100)+0x5f [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\ftw\qqmlthread_p.h @ 227] 00000000`0253b0c0 00000000`65d93b7e Qt5Qmld!QQmlTypeLoaderThread::initializeEngine(class QQmlExtensionInterface * iface = 0x00000000`040a00e0, char * uri = 0x00000000`040a35b8 "QtQuick.Controls.Material")+0x2e [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 861] 00000000`0253b0f0 00000000`65e03e38 Qt5Qmld!QQmlTypeLoader::initializeEngine(class QQmlExtensionInterface * iface = 0x00000000`040a00e0, char * uri = 0x00000000`040a35b8 "QtQuick.Controls.Material")+0xae [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 1239] 00000000`0253b140 00000000`65e09df7 Qt5Qmld!QQmlImportDatabase::importDynamicPlugin(class QString * filePath = 0x00000000`0253b368, class QString * uri = 0x00000000`0253b870, class QString * typeNamespace = 0x00000000`0253b328, int vmaj = 2, class QList<QQmlError> * errors = 0x00000000`0253ba98)+0x668 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmlimport.cpp @ 2104] 00000000`0253b2c0 00000000`65e06e23 Qt5Qmld!QQmlImportsPrivate::importExtension(class QString * qmldirFilePath = 0x00000000`0253b6a8, class QString * uri = 0x00000000`0253b870, int vmaj = 2, int vmin = 1, class QQmlImportDatabase * database = 0x00000000`00356a80, class QQmlTypeLoaderQmldirContent * qmldir = 0x00000000`0407bd60, class QList<QQmlError> * errors = 0x00000000`0253ba98)+0x507 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmlimport.cpp @ 1073] 00000000`0253b610 00000000`65e02560 Qt5Qmld!QQmlImportsPrivate::addLibraryImport(class QString * uri = 0x00000000`0253b870, class QString * prefix = 0x00000000`0253b868, int vmaj = 2, int vmin = 1, class QString * qmldirIdentifier = 0x00000000`0253b860, class QString * qmldirUrl = 0x00000000`0253b858, bool incomplete = false, class QQmlImportDatabase * database = 0x00000000`00356a80, class QList<QQmlError> * errors = 0x00000000`0253ba98)+0x273 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmlimport.cpp @ 1402] 00000000`0253b730 00000000`65d9055e Qt5Qmld!QQmlImports::addLibraryImport(class QQmlImportDatabase * importDb = 0x00000000`00356a80, class QString * uri = 0x00000000`0253b870, class QString * prefix = 0x00000000`0253b868, int vmaj = 2, int vmin = 1, class QString * qmldirIdentifier = 0x00000000`0253b860, class QString * qmldirUrl = 0x00000000`0253b858, bool incomplete = false, class QList<QQmlError> * errors = 0x00000000`0253ba98)+0x280 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmlimport.cpp @ 1628] 00000000`0253b7f0 00000000`65d97f4c Qt5Qmld!QQmlTypeLoader::Blob::addImport(struct QV4::CompiledData::Import * import = 0x00000000`01cc9380, class QList<QQmlError> * errors = 0x00000000`0253ba98)+0x4ee [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 1403] 00000000`0253ba60 00000000`65d966a3 Qt5Qmld!QQmlTypeData::continueLoadFromIR(void)+0x47c [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 2481] 00000000`0253bbc0 00000000`65d9489a Qt5Qmld!QQmlTypeData::dataReceived(class QQmlDataBlob::SourceCodeData * data = 0x00000000`0253bc88)+0xb3 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 2399] 00000000`0253bc00 00000000`65d947f1 Qt5Qmld!QQmlTypeLoader::setData(class QQmlDataBlob * blob = 0x00000000`01c9aa70, class QQmlDataBlob::SourceCodeData * d = 0x00000000`0253bc88)+0x8a [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 1271] 00000000`0253bc50 00000000`65d93ff7 Qt5Qmld!QQmlTypeLoader::setData(class QQmlDataBlob * blob = 0x00000000`01c9aa70, class QString * fileName = 0x00000000`0253bcf0)+0x81 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 1260] 00000000`0253bcb0 00000000`65d9cc11 Qt5Qmld!QQmlTypeLoader::loadThread(class QQmlDataBlob * blob = 0x00000000`01c9aa70)+0x297 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 1136] 00000000`0253bde0 00000000`65db377e Qt5Qmld!QQmlTypeLoaderThread::loadThread(class QQmlDataBlob * b = 0x00000000`01c9aa70)+0x21 [c:\users\qt\work\qt\qtdeclarative\src\qml\qml\qqmltypeloader.cpp @ 876] 2 Id: 24f8.16d0 Suspend: 1 Teb: 000007ff`fffda000 Unfrozen "QQmlDebugServerThread" Child-SP RetAddr Call Site 00000000`032ac128 000007fe`fd5f1430 ntdll!NtWaitForMultipleObjects+0xa 00000000`032ac130 00000000`77492ce3 KERNELBASE!GetCurrentProcess+0x40 00000000`032ac230 00000000`7738bc3d kernel32!WaitForMultipleObjectsEx+0xb3 00000000`032ac2c0 00000000`7738905a USER32!PeekMessageW+0x1cd 00000000`032ac360 00000000`66a44761 USER32!MsgWaitForMultipleObjectsEx+0x2a 00000000`032ac3a0 00000000`66982bc8 Qt5Cored!QEventDispatcherWin32::processEvents(class QFlags<enum QEventLoop::ProcessEventsFlag> flags = class QFlags<enum QEventLoop::ProcessEventsFlag>)+0x7b1 [c:\users\qt\work\qt\qtbase\src\corelib\kernel\qeventdispatcher_win.cpp @ 648] 00000000`032af750 00000000`66982e0e Qt5Cored!QEventLoop::processEvents(class QFlags<enum QEventLoop::ProcessEventsFlag> flags = class QFlags<enum QEventLoop::ProcessEventsFlag>)+0x68 [c:\users\qt\work\qt\qtbase\src\corelib\kernel\qeventloop.cpp @ 135] 00000000`032af790 00000000`665bfcaf Qt5Cored!QEventLoop::exec(class QFlags<enum QEventLoop::ProcessEventsFlag> flags = class QFlags<enum QEventLoop::ProcessEventsFlag>)+0x18e [c:\users\qt\work\qt\qtbase\src\corelib\kernel\qeventloop.cpp @ 212] 00000000`032af840 000007fe`f60f4cc2 Qt5Cored!QThread::exec(void)+0xbf [c:\users\qt\work\qt\qtbase\src\corelib\thread\qthread.cpp @ 515] 00000000`032af8b0 00000000`665cc50d qmldbg_serverd!QQmlDebugServerThread::run(void)+0x2a2 [c:\users\qt\work\qt\qtdeclarative\src\plugins\qmltooling\qmldbg_server\qqmldebugserver.cpp @ 259] 00000000`032af970 00000000`7748652d Qt5Cored!QThreadPrivate::start(void * arg = 0x00000000`003f0e18)+0x19d [c:\users\qt\work\qt\qtbase\src\corelib\thread\qthread_win.cpp @ 380] 00000000`032afa00 00000000`775bc541 kernel32!BaseThreadInitThunk+0xd 00000000`032afa30 00000000`00000000 ntdll!RtlUserThreadStart+0x21