Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.15.2, 6.2.1
-
None
-
-
ddba24535f (qt/qtbase/dev) ddba24535f (qt/tqtc-qtbase/dev) d37d97f639 (qt/qtbase/6.3) d37d97f639 (qt/tqtc-qtbase/6.3)
Description
Any gui application (tested with QGuiApplication or QApplication) which processes the argument
-platformpluginpath /doesnt/exist
(or any other path) appears to treat the directory which the executable is located in, as an additional plugin path. This is despite it not being a default path, and despite specifying a completely different path to load.
Real world example: https://github.com/kovidgoyal/calibre has a headless program that does
PyQt5.QtWidgets.QApplication(['-platformpluginpath', '/usr/lib/calibre/calibre/plugins/', '-platform', 'headless'])
This program loads very, very slowly and strace indicates it will open, statx, mmap every single file in the same directory as /usr/bin/python3 – it seems to be checking each one to see if it is a Qt plugin.
C++ test case attached. Compile it against either qt5 or qt6, install it to /usr/bin/, and try to run it under strace with -platformpluginpath and any non-null string.
Output will include something like:
1736878 readlink("/usr", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin/xset", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 openat(AT_FDCWD, "/usr/bin/xset", O_RDONLY|O_CLOEXEC) = 6 1736878 statx(6, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0755, stx_size=34576, ...}) = 0 1736878 statx(6, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0755, stx_size=34576, ...}) = 0 1736878 mmap(NULL, 34576, PROT_READ, MAP_SHARED, 6, 0) = 0x7f0db314a000 1736878 close(6) = 0 1736878 munmap(0x7f0db314a000, 34576) = 0 1736878 readlink("/usr", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin/xsetbg", "/usr/bin/xloadimage", 1023) = 19 1736878 readlink("/usr", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin/xloadimage", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 openat(AT_FDCWD, "/usr/bin/xloadimage", O_RDONLY|O_CLOEXEC) = 6 1736878 statx(6, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0755, stx_size=208936, ...}) = 0 1736878 statx(6, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0755, stx_size=208936, ...}) = 0 1736878 mmap(NULL, 208936, PROT_READ, MAP_SHARED, 6, 0) = 0x7f0db2516000 1736878 close(6) = 0 1736878 munmap(0x7f0db2516000, 208936) = 0 1736878 readlink("/usr", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin/xsetwacom", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 openat(AT_FDCWD, "/usr/bin/xsetwacom", O_RDONLY|O_CLOEXEC) = 6 1736878 statx(6, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0755, stx_size=60808, ...}) = 0 1736878 statx(6, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0755, stx_size=60808, ...}) = 0 1736878 mmap(NULL, 60808, PROT_READ, MAP_SHARED, 6, 0) = 0x7f0db3144000 1736878 close(6) = 0 1736878 munmap(0x7f0db3144000, 60808) = 0 1736878 readlink("/usr", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 readlink("/usr/bin/xslt-config", 0x7ffe752f83f0, 1023) = -1 EINVAL (Invalid argument) 1736878 openat(AT_FDCWD, "/usr/bin/xslt-config", O_RDONLY|O_CLOEXEC) = 6
This seems extremely wrong, since -platformpluginpath should only append to the search paths, and on Linux where an application is likely not in the same directory as the Qt libraries/plugins (due to either system installation, or rpath) searching in the same directory as the executable is both a waste of time and, in the common case of applications being installed to the system $PATH, probably exceedingly inefficient.