Why does gdb evaluate sqrt(3) to 0?

后端 未结 5 1317
眼角桃花
眼角桃花 2020-11-28 13:40

The square root of 3, as estimated by Wolfram Alpha:

1.7320508075688772935274463415058723669428052538103806280558...

When I do sqrt(3

相关标签:
5条回答
  • 2020-11-28 14:03

    I predict that you didn't do #include <math.h>

    Without a function declaration, C will default the return value of a function to int. A floating point number might come back as 0 depending on the size of your int. C will also not know how to convert the function argument. It will default to passing the argument as whatever type it happens to be. If you pass an integer to sqrt() it will not be converted to a double, but the sqrt() function will interpret the bit pattern as double.

    0 讨论(0)
  • #include <stdio.h>                                                                                                                                                                      
    #include <math.h>
    
    int main()
    {
      printf("sqrt(3): %f\n", sqrt(3));
    
      return 0;
    }
    

    Output:

    josh@josh-ubuntu:~/scratch$ ./a.out 
    sqrt(3): 1.732051
    
    0 讨论(0)
  • 2020-11-28 14:23

    To call a function without debug info, you must explicitly tell gdb the type for the return and arguments, using a function pointer cast. So, for your example:

    (gdb) print ((double (*) (double)) sqrt) (3)
    $1 = 1.7320508075688772
    
    0 讨论(0)
  • 2020-11-28 14:24

    Maybe calling sqrt is not supported ! Maybe because it's a libc function. I don't know the deep reason why, but the following test shows an interesting behaviour:

    double mysqrt(double x) { return sqrt(x) };
    

    Then in a gdb session:

    (gdb) p mysqrt(3)
    $1 = 1.7320508075688772
    (gdb) p sqrt(3)
    $2 = -1209775368
    
    0 讨论(0)
  • 2020-11-28 14:25

    The problem is not the missing function declaration (which isn't missing, since you did include <math.h>).

    The problem is missing debug info for the sqrt you are actually using. Without that debug info, GDB has no clue what parameter type to pass to sqrt(), and what it returns.

    You can get the required debug info on many Linux distributions by installing libc-debuginfo package. Here is what I see on such a system:

    gdb -q ./a.out
    Reading symbols from /tmp/a.out...done.
    (gdb) b main
    Breakpoint 1 at 0x400558: file t.c, line 6.
    (gdb) r
    
    Breakpoint 1, main () at t.c:6
    6     printf("sqrt(3): %f\n", sqrt(3));
    (gdb) p sqrt
    $1 = {<text variable, no debug info>} 0x7ffff7b7fb50 <__sqrt>
    

    Note: "no debug info"

    (gdb) p sqrt(3)
    $2 = 0
    (gdb) p sqrt(3.0)
    $3 = 0
    

    Note: matches your behavior. What sqrt functions do have debug info?

    (gdb) info func sqrt
    All functions matching regular expression "sqrt":
    
    File ../sysdeps/x86_64/fpu/e_sqrt.c:
    double __ieee754_sqrt(double);
    
    File s_csqrt.c:
    complex double __csqrt(complex double);
    
    File ../sysdeps/x86_64/fpu/e_sqrtf.c:
    float __ieee754_sqrtf(float);
    
    File w_sqrtf.c:
    float __sqrtf(float);
    
    File s_csqrtf.c:
    complex float __csqrtf(complex float);
    
    File ../sysdeps/i386/fpu/e_sqrtl.c:
    long double __ieee754_sqrtl(long double);
    
    File w_sqrtl.c:
    long double __sqrtl(long double);
    
    File s_csqrtl.c:
    complex long double __csqrtl(complex long double);
    
    File ../sysdeps/ieee754/dbl-64/mpsqrt.c:
    void __mpsqrt(mp_no *, mp_no *, int);
    
    File w_sqrt.c:
    double __sqrt(double);
    
    (gdb) p __sqrt
    $4 = {double (double)} 0x7ffff7b7fb50 <__sqrt>
    

    Note: __sqrt is at the same address as sqrt, but GDB knows its type!

    (gdb) p __sqrt(3)
    $5 = 1.7320508075688772
    (gdb) p __sqrt(3.0)
    $6 = 1.7320508075688772
    

    One can reasonably argue this is a bug in GDB. Feel free to create one in GDB bugzilla.

    0 讨论(0)
提交回复
热议问题