Date: Wed, 23 Aug 2006 17:43:03 +0900 (JST) From: Tsurutani Naoki <turutani@scphys.kyoto-u.ac.jp> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/102424: printf(3) prints ill result. Message-ID: <200608230843.k7N8h3wg023260@h116.65.226.10.32118.vlan.kuins.net> Resent-Message-ID: <200608230850.k7N8oJ0x088175@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 102424 >Category: bin >Synopsis: printf(3) prints ill result. >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Aug 23 08:50:18 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Tsurutani Naoki >Release: FreeBSD 6.1-STABLE amd64 >Organization: >Environment: System: FreeBSD h116.65.226.10.32118.vlan.kuins.net 6.1-STABLE FreeBSD 6.1-STABLE #3: Fri Aug 11 12:02:50 JST 2006 turutani@h116.65.226.10.32118.vlan.kuins.net:/usr/local/work/usr/obj/usr/src/sys/POLYMER13 amd64 >Description: output via printf(3) is wrong on some special case. on FreeBSD/amd64 and compile for 32bit by gcc (or copied i386 binary), next code prints irregal output: #include <stdio.h> int main() { union { double a; int i[2]; } b; b.i[1] = 0x3fb99999; b.i[0] = 0x99999999; fprintf(stdout, "%f, %.8x %.8x\n", b.a, b.i[1], b.i[0]); return 0; } expected output is: 0.100000, 3fb99999 99999999 but on above mensioned environment, 0.0:0000, 3fb99999 99999999 0x3fb9999999999999 is a little fewer value than 0.1 in decimal. this happens only on amd64, and do not happen with 64bit binary and on i386 machine. "10" is ('0'+1)//('0'+0), and "0:" is ('0'+0)//('0'+10)... character of each digit and its position are inconsequent. >How-To-Repeat: everytime when compile with following way: % gcc -m32 -L/usr/lib32 -B/usr/lib32 foo.c -o foo /etc/make.conf has no CFLAGS. >Fix: After compile all the 32bit libraries with "CFLAGS= -O" instead of "-O2" and install them, no trouble with above code occurs. And compile with "-O2" and install them makes trouble again. As man page of make.conf(5) and /usr/share/mk/sys.mk say, "-O2" in CFLAGS is now a supported feature, so this is a bug. This trouble happend with direct using of __dtoa() defined in src/contrib/gdtoa/dtoa.c, with the same compile options, or use it in libc. Therefore this is thought to be a bug in __dtoa() or compiler. Note that this does not occurs under "-O" libraries even if compile directly with dtoa.c and -O2 options. the following is another code: #include <stdio.h> #include <stdlib.h> #define dtoa __dtoa char* __dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve); int main() { union { double d; int b[2]; } a; int decpt, sign; char *ptr, *ret; a.b[1] = 0x3fb99999; a.b[0] = 0x99999999; ret = __dtoa(a.d, 3, 6, &decpt, &sign, &ptr); printf("decpt = %d\n", decpt); printf("returned string is \"%s\"\n", ret); return 0; } this prints decpt = 0 returned string is "1" on normal case, and decpt = 1 returned string is ":" on wrong case. >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608230843.k7N8h3wg023260>