Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 654076 - dev-qt/qtcore-5.9.4-r2 dev-qt/qtwidgets-5.9.4-r2 issue illegal instructions on Intel Pentium 3
Summary: dev-qt/qtcore-5.9.4-r2 dev-qt/qtwidgets-5.9.4-r2 issue illegal instructions o...
Status: RESOLVED DUPLICATE of bug 648004
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: x86 Linux
: Normal normal (vote)
Assignee: Qt Bug Alias
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-04-25 15:02 UTC by David K. Thompson
Modified: 2018-11-20 22:56 UTC (History)
2 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
emerge --info qtcore (qtcore.info,5.92 KB, text/plain)
2018-05-06 22:36 UTC, Matthew Ogilvie
Details

Note You need to log in before you can comment on or make changes to this bug.
Description David K. Thompson 2018-04-25 15:02:46 UTC
On a pentium3, libQt5core.so is installed successfully, and then exhibits a runtime failure (illegal instruction) first exposed when building qtwidgets as uic is linked against it and executed during the build.

Temporary workaround by editing the ebuilds to disable automatic cpu feature detection for both packages.
        local myconf=(
+                -no-sse2
+                -no-sse3
+                -no-sse4.1
+                -no-sse4.2
+                -no-avx
+                -no-avx2
+                -no-avx512

Upstream bug?

See bug 552942 for similar issue on old version.
Comment 1 Matthew Ogilvie 2018-05-06 22:33:51 UTC
FYI: This isn't high priority for me - I don't actually use this machine and (unrelated) I think its hard drive may fail soon.  But this looks like it is likely to have similar trouble on any non-SSE2 32-bit machine when compiled with gcc 6.4.0-r1, so I'll report what I've found:

I see the same illegal instruction thing on my dual processor athlon-mp machine (-march=athlon-mp), as well as when trying to work around it with (-march=native) or brute force (-march=pentium and empty CPU_FLAGS_X86).  I rebuild qtcore and attempt to build qtwidgets in each case, and in each case uic dies in qHash(QByteArray const&, unsigned int) inside /usr/lib/libQt5Core.so.5.

After the failure, if I run the generated uic manually in gdb without arguments (after examining and bypassing uic_wrapper.sh) I get something like the following:

========================= [SNIP]
# gdb /var/tmp/portage/dev-qt/qtwidgets-5.9.4-r1/work/qtbase-opensource-src-5.9.4/bin/uic
GNU gdb (Gentoo 7.12.1 vanilla) 7.12.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://bugs.gentoo.org/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /var/tmp/portage/dev-qt/qtwidgets-5.9.4-r1/work/qtbase-opensource-src-5.9.4/bin/uic...(no debugging symbols found)...done.
(gdb) run
Starting program: /var/tmp/portage/dev-qt/qtwidgets-5.9.4-r1/work/qtbase-opensource-src-5.9.4/bin/uic 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".

Program received signal SIGILL, Illegal instruction.
0xb7b68d01 in qHash(QByteArray const&, unsigned int) ()
   from /usr/lib/libQt5Core.so.5
(gdb) where
#0  0xb7b68d01 in qHash(QByteArray const&, unsigned int) ()
   from /usr/lib/libQt5Core.so.5
#1  0xb7d209e9 in QTextCodec::codecForName(QByteArray const&) ()
   from /usr/lib/libQt5Core.so.5
#2  0xb7d20cdb in QTextCodec::codecForLocale() () from /usr/lib/libQt5Core.so.5
#3  0xb7b95cac in QString::fromLocal8Bit_helper(char const*, int) ()
   from /usr/lib/libQt5Core.so.5
#4  0xb7cc88e8 in QCoreApplicationPrivate::appName() const ()
   from /usr/lib/libQt5Core.so.5
#5  0xb7ccfea4 in QCoreApplicationPrivate::init() ()
   from /usr/lib/libQt5Core.so.5
#6  0xb7cd0280 in QCoreApplication::QCoreApplication(int&, char**, int) ()
   from /usr/lib/libQt5Core.so.5
#7  0x8006b258 in runUic(int, char**) ()
#8  0x8000b248 in main ()
(gdb) disassemble 
Dump of assembler code for function _Z5qHashRK10QByteArrayj:
   0xb7b68cd0 <+0>:     push   %ebp
   0xb7b68cd1 <+1>:     push   %edi
   0xb7b68cd2 <+2>:     push   %esi
   0xb7b68cd3 <+3>:     push   %ebx
   0xb7b68cd4 <+4>:     sub    $0x1c,%esp
   0xb7b68cd7 <+7>:     call   0xb7b14a90
   0xb7b68cdc <+12>:    add    $0x457324,%ebx
   0xb7b68ce2 <+18>:    mov    0x30(%esp),%eax
   0xb7b68ce6 <+22>:    mov    0x34(%esp),%ecx
   0xb7b68cea <+26>:    mov    (%eax),%ebp
   0xb7b68cec <+28>:    mov    0xc(%ebp),%eax
   0xb7b68cef <+31>:    mov    0x4(%ebp),%edi
   0xb7b68cf2 <+34>:    add    %eax,%ebp
   0xb7b68cf4 <+36>:    mov    -0x25c(%ebx),%eax
   0xb7b68cfa <+42>:    mov    %eax,(%esp)
   0xb7b68cfd <+45>:    movq   (%eax),%xmm0
=> 0xb7b68d01 <+49>:    movq   %xmm0,0x8(%esp)
   0xb7b68d07 <+55>:    mov    0xc(%esp),%edx
   0xb7b68d0b <+59>:    mov    0x8(%esp),%eax
   0xb7b68d0f <+63>:    mov    %edx,%esi
   0xb7b68d11 <+65>:    or     %eax,%esi
   0xb7b68d13 <+67>:    je     0xb7b68d60 <_Z5qHashRK10QByteArrayj+144>
   0xb7b68d15 <+69>:    xor    %edx,%edx
   0xb7b68d17 <+71>:    and    $0x100000,%eax
   0xb7b68d1c <+76>:    mov    %edx,%esi
   0xb7b68d1e <+78>:    or     %eax,%esi
   0xb7b68d20 <+80>:    jne    0xb7b68d50 <_Z5qHashRK10QByteArrayj+128>
   0xb7b68d22 <+82>:    test   %edi,%edi
   0xb7b68d24 <+84>:    je     0xb7b68d80 <_Z5qHashRK10QByteArrayj+176>
   0xb7b68d26 <+86>:    add    %ebp,%edi
   0xb7b68d28 <+88>:    mov    %ecx,%eax
   0xb7b68d2a <+90>:    lea    0x0(%esi),%esi
   0xb7b68d30 <+96>:    mov    %eax,%ecx
   0xb7b68d32 <+98>:    inc    %ebp
   0xb7b68d33 <+99>:    shl    $0x5,%ecx
   0xb7b68d36 <+102>:   sub    %eax,%ecx
   0xb7b68d38 <+104>:   mov    %ecx,%eax
   0xb7b68d3a <+106>:   xor    %ecx,%ecx
   0xb7b68d3c <+108>:   mov    -0x1(%ebp),%cl
   0xb7b68d3f <+111>:   add    %ecx,%eax
   0xb7b68d41 <+113>:   cmp    %ebp,%edi
   0xb7b68d43 <+115>:   jne    0xb7b68d30 <_Z5qHashRK10QByteArrayj+96>
   0xb7b68d45 <+117>:   add    $0x1c,%esp
   0xb7b68d48 <+120>:   pop    %ebx
   0xb7b68d49 <+121>:   pop    %esi
   0xb7b68d4a <+122>:   pop    %edi
   0xb7b68d4b <+123>:   pop    %ebp
   0xb7b68d4c <+124>:   ret    
   0xb7b68d4d <+125>:   lea    0x0(%esi),%esi
   0xb7b68d50 <+128>:   add    $0x1c,%esp
   0xb7b68d53 <+131>:   mov    %edi,%edx
   0xb7b68d55 <+133>:   mov    %ebp,%eax
   0xb7b68d57 <+135>:   pop    %ebx
   0xb7b68d58 <+136>:   pop    %esi
   0xb7b68d59 <+137>:   pop    %edi
   0xb7b68d5a <+138>:   pop    %ebp
   0xb7b68d5b <+139>:   jmp    0xb7b68940
   0xb7b68d60 <+144>:   mov    %ecx,0x4(%esp)
   0xb7b68d64 <+148>:   call   0xb7b8c770 <_Z18qDetectCpuFeaturesv>
   0xb7b68d69 <+153>:   mov    (%esp),%eax
   0xb7b68d6c <+156>:   movq   (%eax),%xmm1
   0xb7b68d70 <+160>:   mov    0x4(%esp),%ecx
   0xb7b68d74 <+164>:   movq   %xmm1,0x8(%esp)
   0xb7b68d7a <+170>:   mov    0x8(%esp),%eax
   0xb7b68d7e <+174>:   jmp    0xb7b68d15 <_Z5qHashRK10QByteArrayj+69>
   0xb7b68d80 <+176>:   mov    %ecx,%eax
   0xb7b68d82 <+178>:   jmp    0xb7b68d45 <_Z5qHashRK10QByteArrayj+117>
End of assembler dump.
(gdb) 
========================= [SNIP]

This file was compiled for package qtcore with (from log):

i486-pc-linux-gnu-g++ -c -o qhash.o  -march=pentium -O2 -pipe -fomit-frame-pointer -fno-stack-protector -std=c++11 -ffunction-sections  -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/qmake -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/qmake/library -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/qmake/generators -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/qmake/generators/unix -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/qmake/generators/win32 -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/qmake/generators/mac -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/include -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/include/QtCore -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/include/QtCore/5.9.4 -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/include/QtCore/5.9.4/QtCore -I../src/corelib/global -I/var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/mkspecs/linux-g++ -DQT_VERSION_STR=\"5.9.4\" -DQT_VERSION_MAJOR=5 -DQT_VERSION_MINOR=9 -DQT_VERSION_PATCH=4 -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL -DQT_NO_FOREACH /var/tmp/portage/dev-qt/qtcore-5.9.4-r2/work/qtbase-opensource-src-5.9.4/src/corelib/tools/qhash.cpp

From the source code ( /var/tmp/portage/dev-qt/qtwidgets-5.9.4-r1/work/qtbase-opensource-src-5.9.4/src/corelib/tools/qhash.cpp ), the logic is split among various inline functions/defines/ifdefs/etc, but looks like depending on various #defines, it will typically try to dynamically detect if SSE4_2 is enabled, and either use some code based around an SSE4_2 CRC32 instruction, or fallback on the simple loop between +96 and +115 in the assembly listing.  Parts of the listing varies by -march, but the bad "movq   (%eax),%xmm0" instruction (SSE2, I think?) is always present.

Speculation: I'm not sure, but maybe gcc (6.4.0-r1) is getting confused by calling a function that has SSE4_2 explicitly enabled (assuming that's what "QT_FUNCTION_TARGET(SSE4_2)" means), and allowing SSE2 instructions even in paths that don't call the SSE4_2 function?  If so, that would probably imply this as a gcc bug.  Or maybe Qt is erroneously detecting SSE2 and setting something in a configuration header file that is overriding the -march argument somehow?

I haven't tried DKT's workaround (local ebuild change), but it looks likely to ifdef out the dynamic CPU tests and SSE4_2 stuff completely, which I could believe would also avoid the SSE2 movq.
Comment 2 Matthew Ogilvie 2018-05-06 22:36:11 UTC
Created attachment 530282 [details]
emerge --info qtcore
Comment 3 David K. Thompson 2018-11-20 19:28:00 UTC
Having reviewed this in more detail, this is definitely a duplicate of the issue in bug 552942, and the fix for that bug no longer works correctly. SSE is forcibly enabled by default for QT5 if the compiler supports it.

The fix for bug 552942 in qt5-build.eclass could be updated to disable sse2 if the cpu does not support it, otherwise the resulting libraries will fail on non SSE2 processors.

This appears to be a deliberate upstream policy decision, and they rely on distributions to either provide both sse2 and non-sse2 library, or explicitly build/configure with -no-sse2 when needed. There are no apparent runtime checks for SSE2 support in the cpu.
https://lists.qt-project.org/pipermail/development/2013-November/014085.html

qtbase-everywhere-src-5.11.1/mkspecs/features/qt_module.prf
sse2:!contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):!host_build:!if(static:qtConfig(shared)) {
    # If the compiler supports SSE2, enable it unconditionally in all of Qt shared libraries
    # (and only the libraries). This is not expected to be a problem because:
    # - on Windows, sharing of libraries is uncommon
    # - on Mac OS X, all x86 CPUs already have SSE2 support (we won't even reach here)
    # - on Linux, the dynamic loader can find the libraries on LIBDIR/sse2/
    # The last guarantee does not apply to executables and plugins, so we can't enable for them.
    QT_CPU_FEATURES.$$QT_ARCH += sse sse2
    QMAKE_CFLAGS += $$QMAKE_CFLAGS_SSE2
    QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2
}


Updated workaround below in the ebuild for qtcore is sufficient to prevent sse2 support being forced on by QT for the older machine. I recognize that a minority are still running older non-sse2 processors, but we do exist!

src_configure() {
        local myconf=(
+                -no-sse2
                $(qt_use icu)
                $(qt_use !icu iconv)
                $(qt_use systemd journald)
        )
        qt5-build_src_configure
}
Comment 4 David K. Thompson 2018-11-20 22:56:12 UTC

*** This bug has been marked as a duplicate of bug 648004 ***