This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Crash in FP printing code


On Mon, Sep 15, 2003 at 07:54:23AM +0200, Jakub Jelinek wrote:
> On Mon, Sep 15, 2003 at 12:02:16AM -0400, Daniel Jacobowitz wrote:
> > I'm seeing a crash on i386-pc-linux-gnu in print_fp.  Test code:
> > 
> > int data[] = {0x00000000, 0x00000000, 0x00000cd0};
> > struct ieee {
> >         unsigned int mantissa1:32;
> >         unsigned int mantissa0:30;
> >         unsigned int quiet_nan:1;
> >         unsigned int one:1;
> >         unsigned int exponent:15;
> >         unsigned int negative:1;
> >         unsigned int empty:16;
> > } *pieee = data;
> > long double *doub = (long double *) data;
> > int main()
> > {
> >   char *ret = 0;
> >   printf ("%.35Lg\n", *doub);
> >   vasprintf (&ret, "%.35Lg", doub);
> 
> This is bogus, vasprintf takes va_list, not long double *. You really should
> never assume what va_list is.

Typo in my test case, reduced from GDB.  The printf crashes, anyway.

> >   printf ("%s\n", ret);
> > }
> > 
> > That number is:
> > 
> > $2 = {mantissa1 = 0, mantissa0 = 0, quiet_nan = 0, one = 0, exponent = 3280, negative = 0, empty = 0}
> > 
> > which ought to be a perfectly valid floating point number, as far as I can
> > tell?
> 
> If you wanted to write 0x1p-13103L, it is 0, 0x80000000, 0xcd0.
> Without the explicit one (exponent is != 0, so it is not denormal and for normal
> numbers it should be set) it is either invalid, or some very weirdo format
> I really cannot find any documentation about.

OK, so it's invalid.  At some point this didn't crash, but now it does. 
GDB has this unfortunate habit of dumping raw data to printf when the
target is corrupted or in unions; each struct value has:
    /* Actual contents of the value.  For use of this value; setting
       it uses the stuff above.  Not valid if lazy is nonzero.
       Target byte-order.  We force it to be aligned properly for any
       possible value.  Note that a value therefore extends beyond
       what is declared here.  */
    union
    {
      long contents[1];
      DOUBLEST force_doublest_align;
      LONGEST force_longest_align;
      CORE_ADDR force_core_addr_align;
      void *force_pointer_align;
    } aligner;

Which makes printf dump arbitrary data as a double.  I'll just have to
add some FP validation code to GDB.

Sorry for the noise.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]