[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: printf-safe checks of invalid long double values
From: |
Pádraig Brady |
Subject: |
Re: printf-safe checks of invalid long double values |
Date: |
Fri, 28 Nov 2014 13:44:35 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 |
On 28/11/14 04:37, Paul Eggert wrote:
> Pádraig Brady wrote:
>> Are these checks backed up by corresponding replacement code?
>> Are these checks correct?
>> Why has glibc not been updated in the 7 years since the checks were added?
>
> As I recall, this comes from an old dispute about what glibc should do when
> asked to print floating-point bit-patterns that cannot be generated by the
> machine's floating-point operations. This has undefined behavior in glibc
> (and POSIX allows this), but undefined behavior can be catastrophic in
> programs like 'od' which will crash when asked to print arbitrary data as if
> it were floating-point. So coreutils insists on a substitute for printf for
> this situation.
>
> See the thread starting here:
>
> http://lists.gnu.org/archive/html/bug-gnulib/2007-06/msg00046.html
Ah right thanks.
glibc no longer crashes since the patch in that thread which is great
(and amazing it was debated). Though there are still these differences
with the attached program, which is why gnulib is replacing printf:
$ sdiff -t -w72 gnulib.out glibc.out
Pseudo-Infinity Pseudo-Infinity
nan | -0[4911 zeros elided]0.000000
nan | -0.000000e+4912
nan | -0e+4912
Pseudo-Zero Pseudo-Zero
nan | 0.000000
nan | 0.000000e+00
nan | 0
Unnormalized number Unnormalized number
nan | 1.550000
nan | 1.550000e+00
nan | 1.55
Pseudo-Denormal Pseudo-Denormal
nan | 0.000000
nan | 8.405258e-4934
nan | 8.40526e-4934
The ironic thing from coreutils' point of view is that we're not actually
using the replacement in od at least, as that uses ftoastr() which calls
snprintf() which is not replaced.
$ printf '\x00\x00\x00\x00\x00\x00\x00\00\xFF\xFF\x00\x00\x00\x00\x00\x00' |
src/od -t fL
0000000 -0e+4912
We used to print "nan" for this value, but since coreutils 8.8 (Dec 2010)
we regressed in this regard due to:
http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commit;h=a71c22fd
So we've 3 options that I see:
1. Include the snprintf-posix gnulib module to fix this od issue,
(but that would also use the replacement code in many more cases).
2. Adjust gnulib's ftoastr() to use the lower level vasnprintf-posix.
That would work, though vasnprintf is not provided by glibc at all,
so perhaps a lower level glibc equivalent function is preferred.
3. Since glibc no longer crashes, and no-one has complained about
these edge cases of invalid numbers, just avoid this replacement altogether
but push for the improvement to output "nan" in these cases in glibc.
As part of that we probably should separate the crash test from
misformatting test in the gnulib module to ensure we still did replace in
the crashing case, but default to not performing the formatting checks.
thanks,
Pádraig.
printf-ldbl-nan.c
Description: Text document