Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 100172 - sys-libs/glibc-2.3.5 + gcc-3.4: fprintf returns wrong value
Summary: sys-libs/glibc-2.3.5 + gcc-3.4: fprintf returns wrong value
Status: RESOLVED DUPLICATE of bug 87631
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: [OLD] Core system (show other bugs)
Hardware: AMD64 Linux
: High critical (vote)
Assignee: Gentoo Toolchain Maintainers
URL:
Whiteboard:
Keywords:
: 93615 103845 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-07-24 18:10 UTC by Randall Nortman
Modified: 2005-08-28 08:51 UTC (History)
4 users (show)

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


Attachments
test case (test.c,326 bytes, text/plain)
2005-07-24 18:12 UTC, Randall Nortman
Details
fputs-return-len.patch (fputs-return-len.patch,1.06 KB, patch)
2005-07-25 08:34 UTC, SpanKY
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Randall Nortman 2005-07-24 18:10:30 UTC
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
Comment 1 Randall Nortman 2005-07-24 18:12:29 UTC
Created attachment 64225 [details]
test case

This is the same test case code included in the bug description.
Comment 2 Randall Nortman 2005-07-25 07:13:06 UTC
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.
Comment 3 SpanKY gentoo-dev 2005-07-25 07:34:18 UTC
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()

Comment 4 Randall Nortman 2005-07-25 08:11:37 UTC
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.
Comment 5 SpanKY gentoo-dev 2005-07-25 08:34:12 UTC
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
Comment 6 Kevin F. Quinn (RETIRED) gentoo-dev 2005-07-25 08:39:09 UTC
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.
Comment 7 SpanKY gentoo-dev 2005-07-25 08:59:07 UTC
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
Comment 8 Kevin F. Quinn (RETIRED) gentoo-dev 2005-07-25 13:30:43 UTC
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)
Comment 9 Kevin F. Quinn (RETIRED) gentoo-dev 2005-07-25 14:01:39 UTC
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.
Comment 10 Georgi Georgiev 2005-07-31 17:36:17 UTC
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?
Comment 11 Jeremy Huddleston (RETIRED) gentoo-dev 2005-07-31 17:58:37 UTC
*** Bug 93615 has been marked as a duplicate of this bug. ***
Comment 12 Aron Griffis (RETIRED) gentoo-dev 2005-08-17 16:08:26 UTC
fwiw, vapier's patch fixes cscope -d
Comment 13 Harald van Dijk (RETIRED) gentoo-dev 2005-08-26 11:43:45 UTC
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.  
Comment 14 SpanKY gentoo-dev 2005-08-26 12:02:54 UTC
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 ...
Comment 15 SpanKY gentoo-dev 2005-08-26 12:37:13 UTC
*** Bug 103845 has been marked as a duplicate of this bug. ***
Comment 16 Tobias Klausmann (RETIRED) gentoo-dev 2005-08-26 13:24:40 UTC
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.
Comment 17 SpanKY gentoo-dev 2005-08-26 21:29:50 UTC
forced revbump to push out update

*** This bug has been marked as a duplicate of 87631 ***
Comment 18 Randall Nortman 2005-08-28 08:51:13 UTC
That fixes it for me.  Thanks.