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