The standard library function fprintf is supposed to return the number of characters printed to the stream. In some cases, on amd64, it does not. I have created a very simple C program which demonstrates one case in which it returns the wrong value and another case where the value is correct. printf returns the correct value in both cases, which is bizarre since, according to my reading of the glibc source, both functions are implemented in terms of the same underlying function, vfprintf. I compiled the same program in a 32-bit chroot on the same system and it works fine in all cases, so this seems to be a 64-bit problem. I'm reporting this bug to Gentoo because the glibc maintainers request that bugs first be reported to distributions, as distributions apply their own patches. This seems likely to be an upstream bug to me, though. Here is the C test case: ----- Begin test.c ----- #include <stdio.h> int main(int argc, char* argv[]) { int rc = 0; rc = fprintf(stdout, "%s", "aa\n"); /* rc=1 on my amd64 system */ printf("rc=%d (should be 3)\n", rc); rc = fprintf(stdout, "%s\n", "aa"); printf("rc=%d (should be 3)\n", rc); rc = printf("%s", "aa\n"); printf("rc=%d (should be 3)\n", rc); } ----- End test.c ----- Reproducible: Always Steps to Reproduce: 1. Compile above test case (gcc test.c) 2. Execute result (./a.out) 3. Examine output closely (the first case should fail) Actual Results: This is the output I see: ----- aa rc=1 (should be 3) aa rc=3 (should be 3) aa rc=3 (should be 3) ----- As you can see, the first test case fails. Output of emerge info on my system: Gentoo Base System version 1.6.13 Portage 2.0.51.22-r2 (default-linux/amd64/2004.3, gcc-3.4.3, glibc-2.3.5-r0, 2.6.12-gentoo-r4 x86_64) ================================================================= System uname: 2.6.12-gentoo-r4 x86_64 AMD Athlon(tm) 64 Processor 3000+ dev-lang/python: 2.3.5 sys-apps/sandbox: 1.2.10 sys-devel/autoconf: 2.13, 2.59-r6 sys-devel/automake: 1.4_p6, 1.5, 1.6.3, 1.7.9-r1, 1.8.5-r3, 1.9.5 sys-devel/binutils: 2.15.92.0.2-r10 sys-devel/libtool: 1.5.18-r1 virtual/os-headers: 2.6.11-r2 ACCEPT_KEYWORDS="amd64" AUTOCLEAN="yes" CBUILD="x86_64-pc-linux-gnu" CFLAGS="-pipe -O2" CHOST="x86_64-pc-linux-gnu" CONFIG_PROTECT="/etc /usr/kde/2/share/config /usr/kde/3.3/env /usr/kde/3.3/share/config /usr/kde/3.3/shutdown /usr/kde/3.4/env /usr/kde/3.4/share/config /usr/kde/3.4/shutdown /usr/kde/3/share/config /usr/lib/X11/xkb /usr/lib/mozilla/defaults/pref /usr/share/config /var/qmail/control" CONFIG_PROTECT_MASK="/etc/gconf /etc/terminfo /etc/env.d" CXXFLAGS="-pipe -O2" DISTDIR="/usr/portage/distfiles" FEATURES="autoconfig distlocks sandbox sfperms strict" GENTOO_MIRRORS="http://gentoo.ccccom.com http://mirrors.tds.net/gentoo ftp://mirrors.tds.net/gentoo ftp://ftp.snt.utwente.nl/pub/os/linux/gentoo ftp://ftp.heanet.ie/pub/gentoo/" MAKEOPTS="-j2" PKGDIR="/usr/portage/packages" PORTAGE_TMPDIR="/var/tmp" PORTDIR="/usr/portage" SYNC="rsync://rsync.us.gentoo.org/gentoo-portage" USE="amd64 X aalib acpi alsa apache2 avi berkdb bitmap-fonts bzlib crypt cups curl directfb eds emacs encode esd exif fam fbcon flac foomaticdb fortran gd gdbm gif gphoto2 gpm gtk gtk2 guile imagemagick imap imlib ipv6 jabber java jpeg lzw lzw-tiff mad maildir mbox mikmod motif mozilla mp3 mpeg multilib ncurses nls offensive ogg oggvorbis opengl oscar oss pam pdflib perl png postgres ppds python qt quicktime readline scanner sdl slang spell ssl svg tcltk tcpd tiff truetype truetype-fonts type1-fonts usb userlocales vorbis xml2 xmms xpm xv zlib userland_GNU kernel_linux elibc_glibc" Unset: ASFLAGS, CTARGET, LANG, LC_ALL, LDFLAGS, LINGUAS, PORTDIR_OVERLAY
Created attachment 64225 [details] test case This is the same test case code included in the bug description.
An explanation of why I marked this bug "critical", though the bug seems minor: The bug results in a crash of at least one program I have tested: db_dumb (from Berkeley DB, sys-libs/db), which is an important program as many other programs rely on this package. More importantly, I can imagine how this could easily result in non-fatal bugs in other programs, and in particular could result in security bugs or loss of data. Consider, for example, an application which allocates a buffer based on the value returned from fprintf. If the buffer is made too small, a buffer overflow could easily result. I don't know that this actually happens in any application, but it certainly could. The sorts of applications that actually check the return value of fprintf (few and far between, to be sure) are exactly the sorts where correctness and stability are critical.
the problem is that the first fprintf in your example gets optimized to fputs which just returns 0 or 1 ... run `objdump -d` on the test binary and look at the main func ... you should see that the first fprintf() is really an optimized call to fputs()
You're absolutely correct. And so the difference is not 64-bit vs. 32-bit versions of glibc, it's gcc 3.4.3 (the version I have on my 64-bit system, which optimizes fprintf to fputs) vs. gcc 3.3.5 (the version I have on my 32-bit system, which does not optimize this call). So this is a bug in gcc, then? It seems to optimize the call even when -O0 is specified (which is the default anyway). I suppose one of the -f options might explicitly disable it, but I'm not sure which one. Anyway, I consider it certainly a bug when an optimization changes the return value of a function, especially when -O0 is specified.
Created attachment 64279 [details, diff] fputs-return-len.patch the puts() function in glibc returns the # of bytes written so this patch changes fputs to do the same
Just tried it myself (32-bit x86) - got the erroneous result with gcc-3.4.3, however gcc-3.4.4 gives correct results, so presumably upstream have noticed and fixed whatever bug caused it. I find gcc-3.4.4 much more reliable than 3.4.3, btw.
gcc-3.4.3 and gcc-3.4.4 is generating bum code for me ... gcc-3.3.6 and gcc-4.0.1 are not though
spanky; hmm - I re-emerged gcc-3.4.4 a few days ago (21st July) to add the boundschecker so maybe there's been a change since you emerged. I've uploaded the emerge log to http://dev.gentoo.org/~kevquinn/gcc/3636-gcc-3.4.4.log if you want to compare which patches went in. $ gcc -v Reading specs from /usr/lib/gcc/i686-pc-linux-gnu/3.4.4/specs Configured with: /var/tmp/portage/gcc-3.4.4/work/gcc-3.4.4/configure --enable-version-specific-runtime-libs --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/3.4.4 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.4/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.4 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.4/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.4/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.4/include/g++-v3 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --disable-libunwind-exceptions --disable-multilib --enable-java-awt=gtk --enable-languages=c,c++,java,f77 --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu Thread model: posix gcc version 3.4.4 (Gentoo Hardened 3.4.4, HTB-3.4.4-1.00, ssp-3.4.4-1.0, pie-8.7.8)
couldn't find a directly relevant entry in gcc's bugzilla, but here's a couple that are somewhat relevant: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9967 Some standard C function calls should not be replaced when optimizing for size http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21982 GCC should combine adjacent stdio calls Personally I dislike the idea of the compiler rewriting calls to the standard library functions.
This doesn't have to be marked amd64 anymore, no? Should this bug block Bug #93615 or should that one depend on this one? Or is it all the same?
*** Bug 93615 has been marked as a duplicate of this bug. ***
fwiw, vapier's patch fixes cscope -d
Is this bug #87631, or is this another problem? There was no revbump for that, so it would explain why one gcc 3.4.4 fails where another succeeds.
i thought i checked and rebuilding gcc w/out the check patch did not fix the test case here ... maybe that was a diff bug though can people still experiencing this bug re-emerge their gcc-3.4.4 and see if that resolves the issue ? if so i'll revbump the ebuild ...
*** Bug 103845 has been marked as a duplicate of this bug. ***
I had this problem, so I just remerged gcc: # genlop -t gcc [...snip...] Thu Jun 2 21:04:51 2005 >>> sys-devel/gcc-3.4.4 # emerge gcc -pv These are the packages that I would merge, in order: Calculating dependencies ...done! [ebuild R ] sys-devel/gcc-3.4.4 (-altivec) -bootstrap -boundschecking -build +fortran -gcj +gtk -hardened -ip28 (-multilib) -multislot (-n32) (-n64) +nls -nocxx -nopie -nossp -objc -static -vanilla 44 kB Total size of downloads: 44 kB Downloaded file: /usr/portage/distfiles/gcc-3.4.4-patches-1.5.tar.bz2 Problem is gone now. Hence, I'd recommend a bump on gcc.
forced revbump to push out update *** This bug has been marked as a duplicate of 87631 ***
That fixes it for me. Thanks.