coreutils
[Top][All Lists]
Advanced

[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.

Attachment: printf-ldbl-nan.c
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]