Details
-
Bug
-
Resolution: Out of scope
-
Not Evaluated
-
None
-
5.7.1, 5.7, 5.8, 5.9.0, 5.9.1, 5.9.2, 5.9.3, 5.10.0, 5.10.1
-
None
-
Windows 10, with Symantec Data Loss Prevention installed.
NOTE: I have not managed to find a consistent repro for this myself. I don't have a copy of Symantec DLP (and it's like the only product they have that they don't provide a free trial version of), so all the information I managed to collect was collected by having customers run through convoluted repro steps with private builds of our product with additional logging and analysis hooks.
The most reliable approach I've found to determining whether this problem WILL occur on a machine running DLP is to launch with a debugger, with a breakpoint on QThreadData::current() and a breakpoint on main(), and make sure the main() breakpoint is hit first.Windows 10, with Symantec Data Loss Prevention installed. NOTE: I have not managed to find a consistent repro for this myself. I don't have a copy of Symantec DLP (and it's like the only product they have that they don't provide a free trial version of), so all the information I managed to collect was collected by having customers run through convoluted repro steps with private builds of our product with additional logging and analysis hooks. The most reliable approach I've found to determining whether this problem WILL occur on a machine running DLP is to launch with a debugger, with a breakpoint on QThreadData::current() and a breakpoint on main(), and make sure the main() breakpoint is hit first.
Description
- Events are only passed through application event filters if the receiver of the event is on the main thread.
- Qt considers "the main thread" to be the first thread to invoke QThreadData::current()
- Initialization of non-local static variables typically happens before execution of main(), but is not guaranteed to happen on the same thread that executes main().
In the event that dynamic initialization of non-local statics happens on a non-main thread, any QObject creation or anything else that causes QThreadData::current() to be invoked will break application event filters.
We're primarily seeing this with customers using Symantec Data Loss Prevention on Windows 10, where it repros consistently (Symantec seems to be hooking CreateProcess in the explorer.exe process to override default image loader behavior somehow, so that all image load initialization happens on a worker thread that exits before execution of main even begins), but I have managed to inadvertently make it happen myself a couple of times by throwing a lot of procdump attach attempts at process startup. Because, as mentioned above, there's no guarantees I can find about threading environment during initialization of non-local statics.
(NOTE: Just to get ahead of a likely source of confusion, Windows 10 added a new parallel load mechanism; this is not that. The default Win10 parallel load only parallelizes the load/memory mapping part of image load; all initialization is still done on what will become the main thread. Changing the registry settings to disable the native Win10 parallel loading behavior DID NOT stop the bug, the Symantec image load behavior was still used.)
WORKAROUNDS:
- Replace non-local static variables in question with local statics returned by reference from static methods (see Effective C++, Item 4, where he's talking about "order of initialization of non-local static objects defined in different translation units"). This is what we're currently doing. But it looks like Mapbox GL Native's Qt implementation involves at least one non-local static that will trigger the issue, so this approach has its issues.
- Dynamically load libraries with problematic non-local statics after start of main.