Bug#228421: gcc 3.0.4 generates bad code on Debian 3.0/PARISC
Package: gcc
Version: 2:3.0.4-5
Kernel: Linux hp 2.4.24-pa0 #1 Sun Jan 11 18:48:21 CET 2004 parisc unknown
glibc: Version: 2.2.5-11.5
GCC 3.0.4 included in Debian 3.0 generates bad code on PARISC platform. The
original apache 1.3.26 distributed in this port returns lines full of zeroes
in the size field of the files between 1 and 100 MB :
linux-2.4.20-wt17.tar.bz2 08-Jun-2003 11:05 0.0000000000000000000000000000000000000000000000000000M
patch-2.4.20-to-2.4.20-wt17.bz2 08-Jun-2003 11:04 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000M
CONTENTS-2.4.20-wt17 08-Jun-2003 10:52 18k
... and so on.
So I have recompiled 1.3.29 from sources with gcc-3.0.4, and the problem was
exactly the same. Digging through the code, I discovered that for exactly
these files, apache uses a floating point representation for the size, and it
calls ap_rprintf() which is sort of an sprintf(), with (size/1048576.0) as an
argument, and "%4.1fM" as the format string.
Replacing the format with "%4eM" gave me something interesting :
linux-2.4.20-wt17.tar.bz2 08-Jun-2003 11:05 8.417643e-53M
patch-2.4.20-to-2.4.20-wt17.bz2 08-Jun-2003 11:04 1.284430e-57M
CONTENTS-2.4.20-wt17 08-Jun-2003 10:52 18k
I've read the complete implementation of ap_rprintf(), and it seems correct
to me. But some double arguments are passed as va_args at several places. So
I thought that it could be possible that gcc does not handle this very well.
Then I recompiled only util_script.c and ap_snprintf.c with gcc-3.3.2, not
changing anything else, and apache now reports correct sizes :
linux-2.4.20-wt17.tar.bz2 08-Jun-2003 11:05 30.1M
patch-2.4.20-to-2.4.20-wt17.bz2 08-Jun-2003 11:04 7.2M
CONTENTS-2.4.20-wt17 08-Jun-2003 10:52 18k
Now I've found that it's very easy to reproduce. Consider this trivial program :
#include <stdio.h>
#include <stdlib.h>
main() {
printf("%4.1f\n", 1.23456);
}
Now, test it :
# gcc -O2 -o fp-test fp-test.c
# ./fp-test
0.0
# gcc -O1 -o fp-test fp-test.c
# ./fp-test
1.2
# gcc-3.3.2-parisc -O2 -o fp-test fp-test.c
# ./fp-test
1.2
# gcc -v
Reading specs from /usr/lib/gcc-lib/hppa-linux/3.0.4/specs
Configured with: ../src/configure -v --enable-languages=c,c++,f77,proto,objc --prefix=/usr --infodir=/share/info --mandir=/share/man --enable-shared --with-gnu-as --with-gnu-ld --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-checking --enable-threads=posix --with-cpp-install-dir=bin hppa-linux
Thread model: posix
gcc version 3.0.4
# gcc-3.3.2-parisc -v
Reading specs from /usr/lib/gcc-lib/hppa1.1-hp-linux-gnu/3.3.2/specs
Configured with: ../gcc-3.3.2/configure --prefix=/usr --with-gnu-ld --with-gnu-as --host=hppa1.1-hp-linux-gnu --target=hppa1.1-hp-linux-gnu --with-cpu=7100LC --enable-languages=c,c++ --disable-nls --disable-locale --enable-shared --enable-target-optspace --enable-version-specific-runtime-libs --program-suffix=-3.3.2-parisc --enable-threads
Thread model: posix
gcc version 3.3.2
So it seems that the work-around simply is to switch back to -O1.
Unfortunately, I tried about 20 -fno-XXX with -O2 to find the culprit,
but I couldn't. And I don't remember how I can dump the -O1 and -O2
equivalents.
I hope I didn't forget anything. At the moment, I don't know if there are
packages other than apache which have been affected by this bug.
Regards,
Willy
Reply to: