Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QThreadPrivate::finish segmentation fault in static object destructor



  • I've got following simplified code (in original project the code if more complicated):

    namespace show_msg_thread
    {
        class CShowMsg
        {
        public:
            CShowMsg() = default;
            ~CShowMsg() = default;
     
            CShowMsg(const CShowMsg&) = delete;
            CShowMsg& operator=(const CShowMsg&) = delete;
     
            void WaitUntilProcessed()
            {
                m_event.Wait();
            }
     
            void ProcessInCurrentThread()
            {
                {
                    int argc = 1;
                    char arg0[] = "TestAppLinux";
     
                    char* argv[] = { arg0};
     
                    QApplication app(argc, argv);
                    QMessageBox msgBox(QMessageBox::Warning, QString::fromWCharArray(L"LinuxTestApp"),
                                       QString("Test message"), QMessageBox::Yes | QMessageBox::No);
                    msgBox.exec();
                }
                m_event.Set();
            }
     
        private:
            Event m_event;
        };
     
        class CShowThread
        {
        public:
            CShowThread(const CShowThread&) = delete;
            CShowThread& operator=(const CShowThread&) = delete;
     
            void EnqueueRequest(CShowMsg* pRequest)
            {
                {
                    std::scoped_lock<std::mutex> guard(m_msgMutex);
                    m_msgPtr = pRequest;
                }
                m_msgEvent.Set();
            }
     
            static CShowThread& Instance()
            {
                static CShowThread instance;
                return instance;
            }
     
        private:
            CShowThread()
                : m_bAtomicStopThread(false)
            {
                m_thread = std::thread(&CShowThread::ProcessShowReportRequests, this);
            }
     
            ~CShowThread()
            {
                m_bAtomicStopThread = true;
     
                m_msgEvent.Set();
                m_thread.join();
            }
     
            void ProcessShowReportRequests()
            {
                do
                {
                    m_msgEvent.Wait();
     
                    while (true)
                    {
                        CShowMsg* pCurrentMsg = nullptr;
                        {
                            std::lock_guard<std::mutex> lock(m_msgMutex);
     
                            if(m_msgPtr != nullptr)
                            {
                                pCurrentMsg = m_msgPtr;
                                m_msgPtr = nullptr;
                            }
                            else
                                break;
                        }
                        if(pCurrentMsg != nullptr)
                            pCurrentMsg->ProcessInCurrentThread();
                    }
                } while (!m_bAtomicStopThread);
            }
     
        private:
            std::thread m_thread;
            std::atomic_bool m_bAtomicStopThread;
     
            CShowMsg* m_msgPtr = nullptr;
            std::mutex m_msgMutex;
            Event m_msgEvent;
        };
     
        void Initialize()
        {
            CShowThread::Instance();
        }
     
        void ShowDialog()
        {
            CShowMsg msg;
            CShowThread::Instance().EnqueueRequest(&msg);
            msg.WaitUntilProcessed();
        }
    }
     
    int main()
    {
        {
            show_msg_thread::Initialize();
            show_msg_thread::ShowDialog();
        }
        std::cout << "Finished" << std::endl;
        return 0;
    }
    

    Here Event is just wrapper class around std::conditional_variable.

    When singleton instance is terminated there is a segmentation fault. So I see in output Finished string. Then destructor of CShowThread is called and segmentation fault is occurred. If I comment QApplication creation (and showing QMessageBox) in ProcessInCurrentThread function then everything is fine. However when I uncomment only QApplication creation then the problem occurs.
    As it seen from the callstack, my app crashes in QThreadPrivate::finish method, but I wasn't able to find the reason.
    Could u please tell why this happens?

    Additional info: the code from show_msg_thread namespace is part of shared library which is used for getting some info and showing this info in dialog in another thread. Application which uses this library isn't Qt application - that's why I need create QApplication instance inside of the library.



  • https://doc.qt.io/qt-5/qapplication.html#QApplication

    Warning: The data referred to by argc and argv must stay valid for the entire lifetime of the QApplication object. In addition, argc must be greater than zero and argv must contain at least one valid character string.


Log in to reply