Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.9.2
-
None
-
Windows OS
-
851c226247d692a608d78a1d7f9e621f4a82f40d (qtbase/5.9, 4.11.2017, 5.9.4)
Description
When QFileSystemWacther is created on OS Windows it installs a native event filter (QWindowsRemovableDriveListener) in QCoreApplication::eventDispatcher(), see QWindowsFileSystemWatcherEngine::QWindowsFileSystemWatcherEngine(). When QFileSystemWacther is destroyed it removes the filter from QAbstractEventDispatcher::instance(), see QAbstractNativeEventFilter::~QAbstractNativeEventFilter(). For GUI thread that's the same, for a background thread it's different. So if you create QFileSystemWacther in a background thread and delete it there, there will be a dangling pointer in QCoreApplication::eventDispatcher() which will almost certainly lead to a crash when handling native events.
It looks like a regression somewhere between Qt 5.5 and Qt 5.9.2, since I checked with Qt 5.4 it didn't crash (actually it used to work even for Qt 4). I attached a project for your convenience, just select "test" -> crash it!" from the application menu. But it's reproducible with the following line of code:
QtConcurrent::run([](){ delete new QFileSystemWatcher; });
EDIT: Added a backtrace in case someone googles by stack:
> Qt5Cored.dll!QAbstractEventDispatcher::filterNativeEvent(const QByteArray & eventType, void * message, long * result) Line 467 C++
qwindowsd.dll!QWindowsContext::windowsProc(HWND__ * hwnd, unsigned int message, QtWindows::WindowsEventType et, unsigned __int64 wParam, __int64 lParam, __int64 * result, QWindowsWindow * * platformWindowPtr) Line 899 C++
qwindowsd.dll!qWindowsWndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1332 C++
user32.dll!UserCallWinProcCheckWow() Unknown
user32.dll!DispatchClientMessage() Unknown
user32.dll!__fnDWORD() Unknown
ntdll.dll!KiUserCallbackDispatcherContinue() Unknown
user32.dll!NtUserPeekMessage() Unknown
user32.dll!PeekMessageW() Unknown
Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 559 C++
qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 74 C++
Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 135 C++
Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 212 C++
Qt5Cored.dll!QCoreApplication::exec() Line 1291 C++
Qt5Guid.dll!QGuiApplication::exec() Line 1680 C++
Qt5Widgetsd.dll!QApplication::exec() Line 2911 C++
qfilesystemwatcher_crash.exe!main(int argc, char * * argv) Line 10 C++
qfilesystemwatcher_crash.exe!WinMain(HINSTANCE__ * _formal, HINSTANCE_ * __formal, char * __formal, int __formal) Line 104 C++
qfilesystemwatcher_crash.exe!invoke_main() Line 107 C++
qfilesystemwatcher_crash.exe!__scrt_common_main_seh() Line 283 C++
qfilesystemwatcher_crash.exe!__scrt_common_main() Line 326 C++
qfilesystemwatcher_crash.exe!WinMainCRTStartup() Line 17 C++
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown