-
Bug
-
Resolution: Unresolved
-
P0: Blocker
-
None
-
6.9.1
-
None
-
OS: Windows 11
Compiler: MinGW-w64-x86_64-13.1.0-release-posix-seh-msvcrt-rt_v11-rev1.7z
Custom Qt v6.9.1 causes SIGSEGV on exit
Context
I build the Qt Library (https://code.qt.io/qt/qt5.git tag: v6.9.1) myself for Ubuntu Linux (x86_64, aarch64) and Windows (x86_64) to include single Docker image to build all 3 targeted OS/architectures in a single CI/CD pipeline using a single Docker image.
The Windows app is cross compiled from Linux using MinGW and unittested using Wine from the Docker container as well.
The Windows Qt Framework is build native on Windows 11.
Not the full Qt framework is build to keep small and thus the Docker image.
(see attachment: config.summary)
Issue
After upgrading a working application from Qt v6.8.1 to v6.9.1 the application hung on exit in a destructor from a thread called "Thread(pooled)":
set_thread_data(QThreadData*)::Cleanup::~Cleanup()
set_thread_data(QThreadData*)::Cleanup::~Cleanup(): endbr64 push %rsi push %rbx sub $0x28,%rsp lea 0x27762f(%rip),%rcx # 0x7fffe7a292e0 <__emutls_v._ZL17currentThreadData> call 0x7fffe7947570 <__emutls_get_address> mov (%rax),%rbx mov %rax,%rsi SIGSEGV signal on the next 'mov' instruction where '$rbx' seems to be a nullptr or uninitialized. mov 0x50(%rbx),%rax cmpb $0x0,0x8e(%rbx) jne 0x7fffe77b1ce8 <set_thread_data(QThreadData*)::Cleanup::~Cleanup()+72> lock subl $0x1,0x80(%rbx) je 0x7fffe77b1d00 <set_thread_data(QThreadData*)::Cleanup::~Cleanup()+96> movq $0x0,(%rsi) add $0x28,%rsp pop %rbx pop %rsi ret nopl 0x0(%rax) mov 0x8(%rax),%rcx mov $0x1,%edx call 0x7fffe77b19e0 <QThreadPrivate::finish(bool)> jmp 0x7fffe77b1cc9 <set_thread_data(QThreadData*)::Cleanup::~Cleanup()+41> nopl 0x0(%rax,%rax,1) mov %rbx,%rcx call 0x7fffe76f7560 <QThreadData::~QThreadData()> mov $0x90,%edx mov %rbx,%rcx call 0x7fffe79461b0 <operator delete(void*, unsigned long long)> movq $0x0,(%rsi) add $0x28,%rsp pop %rbx pop %rsi ret nop data16 cs nopw 0x0(%rax,%rax,1) nop
static void set_thread_data(QThreadData *data) noexcept { if (data) { struct Cleanup { Cleanup() { QThreadStoragePrivate::init(); } ~Cleanup() { destroy_current_thread_data(currentThreadData); } }; static thread_local Cleanup currentThreadCleanup; } currentThreadData = data; }
Isolation Steps
1) Single File Test Application
I isolated the problem a created a simple application causing the problem when a QPushButton instance not parented by a QWidget.
#include <QApplication> #include <QDebug> #include <QPushButton> int main(int argc, char* argv[]) { int rv{0}; QApplication app(argc, argv); QWidget* wgt{nullptr}; if (argc == 1) // Makes it hang when application exists. When debugging causes a SIGSEGV signal. wgt = new QPushButton(QString(qVersion()) + "/" + QT_VERSION_STR); else // Seems to be no problem. wgt = new QWidget(); wgt->setWindowTitle("Qt Test Application"); wgt->resize(300, 120); wgt->show(); rv = app.exec(); delete wgt; qDebug() << "Exiting with code:" << rv; return rv; }
2) Compiler
To be sure the compiler MinGW-w64-x86_64-13.1.0-release-posix-seh-msvcrt-rt_v11-rev1.7z was downloaded from Qt to build the framework.
3) Using Pre-build Windows Qt v6.9.1 Framework
To narrow the problem down I used the downloaded the prebuild Qt v6.9.1 full framework.
This does NOT seem to cause the issue.
Reproduce
To build the Qt framework I use a single bash script build-qt-lib.sh (qt-v6.9.1-core-bug.zip) also used from Windows in a Cygwin environment.
Found the problem
In narrowing down the problem to a certain version the cause is probably related to a used toolchain.
I've got 2 version of v6.9.1 and one is broken. At first glance it looks like a GNU toolchain mismatch.
g++.exe (GCC) 13.1.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
g++.exe (x86_64-posix-seh-rev1, Built by MinGW-Builds project) 13.1.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GCC Bug
After building the Qt framework using MinGW v13.2.0 I found that my libraries build with the MinGW cross compiler with the the same version (13.2.0) on Linux had an issue dynamically linking.
When starting the executable from Windows it could not link _ZSt21ios_base_library_initv (stdc++-6.dll).
When starting it from Linux Wine there is no issue which is probably solved by Wine itself with its dynamic linker. I found the probable cause in issue GCC Bugzilla – Bug 116159 which is solved in GCC v14.3