Code generation bug with -O2 (-foptimize-sibling-calls)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Linaro GCC |
Fix Released
|
High
|
Andrew Stubbs | ||
gcc |
Fix Released
|
High
|
|||
gcc-4.6 (Ubuntu) |
Fix Released
|
High
|
Unassigned |
Bug Description
See <URL:http://
Jakub Jelinek recently added a self-contained example where this bug triggered with normal C code.
The affected bug triggered about half a dozen errors in the Lilypond code base. These bugs are very hard to debug because they occur in connection with sibling call optimization, so at the time of the resulting segfault, the stack frame of the caller with the faulty code no longer exists.
The bug affects all architectures, though the probability for it to hit is quite higher on the 32bit i686 architecture, due to fewer available registers.
If Jakub's statement that he can't detect the bug in the 4.6 codebase but on current trunk (4.7) is correct, then the bug has been introduced into Oneiric via distribution specific patches.
It definitely is in the compiler of vanilla Ubuntu 11.10, and both the c++ test case I sent as well as the much simpler C test case Jakub constructed trigger.
An option workaround is to use -fno-optimize-
Since potentially the reliability of all code compiled with gcc (the vast majority of the Ubuntu code base) is affected, I am marking this as critical. Since bad code can also have security implications, I would suggest not taking this all too lightly.
In my opinion, if the bug can be traced back to a distribution specific patch taken from the 4.7 branch, this patch needs to get backed out and all those parts of Ubuntu having gcc in their build dependencies need to get recompiled.
ProblemType: Bug
DistroRelease: Ubuntu 11.10
Package: gcc-4.6-base 4.6.1-9ubuntu3
ProcVersionSign
Uname: Linux 3.0.0-13-generic i686
ApportVersion: 1.23-0ubuntu4
Architecture: i386
Date: Tue Nov 29 09:55:27 2011
Dependencies:
InstallationMedia: Ubuntu 11.10 "Oneiric Ocelot" - Release i386 (20111011)
ProcEnviron:
LANGUAGE=en_US:en
PATH=(custom, user)
LANG=en_US.UTF-8
SHELL=/bin/bash
SourcePackage: gcc-4.6
UpgradeStatus: No upgrade log present (probably fresh install)
Changed in gcc: | |
importance: | Unknown → High |
status: | Unknown → In Progress |
Changed in gcc-4.6 (Ubuntu): | |
importance: | Undecided → High |
status: | New → Confirmed |
Changed in gcc: | |
status: | In Progress → Fix Released |
Changed in gcc-linaro: | |
status: | New → Confirmed |
Changed in gcc-linaro: | |
status: | In Progress → Fix Committed |
Changed in gcc-linaro: | |
status: | Fix Committed → In Progress |
status: | In Progress → Fix Released |
Created attachment 25921
Boiled down source code. Bad code for last function.
The following boiled down code produces a jmp to Grob::internal_ set_property where the implicit first call argument (this) is equal to the explicit second call argument instead of the actual this pointer. The guilty code sequence is
.L4: state cfa_offset 8 cfa_offset 4 nal_set_ propertyEPvS0_
movl %ebx, 40(%esp)
movl %ebx, 32(%esp)
movl %eax, 36(%esp)
addl $24, %esp
.cfi_remember_
.cfi_def_
popl %ebx
.cfi_def_
.cfi_restore 3
jmp _ZN4Grob21inter
Version is LTO_WRAPPER= /usr/lib/ gcc/i686- linux-gnu/ 4.6.1/lto- wrapper pkgversion= 'Ubuntu/ Linaro 4.6.1-9ubuntu3' --with- bugurl= file:// /usr/share/ doc/gcc- 4.6/README. Bugs --enable- languages= c,c++,fortran, objc,obj- c++,go --prefix=/usr --program- suffix= -4.6 --enable-shared --enable- linker- build-id --with-system-zlib --libexecdir= /usr/lib --without- included- gettext --enable- threads= posix --with- gxx-include- dir=/usr/ include/ c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable- clocale= gnu --enable- libstdcxx- debug --enable- libstdcxx- time=yes --enable-plugin --enable-objc-gc --enable- targets= all --disable-werror --with-arch-32=i686 --with-tune=generic --enable- checking= release --build= i686-linux- gnu --host= i686-linux- gnu --target= i686-linux- gnu
Using built-in specs.
COLLECT_GCC=g++
COLLECT_
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)
Compilation options are -O2
This is from Lilypond source code and causes a segfault.