bin/102424: printf(3) prints ill result.
Tsurutani Naoki
turutani at scphys.kyoto-u.ac.jp
Wed Aug 23 08:50:25 UTC 2006
>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 at 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:
More information about the freebsd-bugs
mailing list