8

Possible Duplicate:
Why does gdb evaluate sqrt(3) to 0?

C newbie here. There must be an obvious explanation why gdb gives strange outputs when trying to use math.h functions in-line. For example, the fabs function below is supposed to take the absolute value, and return a double.

(gdb) p cos(2*3.141/4)
$13 = 1073291460
(gdb) p fabs(-3)    
$14 = 0
(gdb) p fabs(3)
$15 = 0
(gdb) p fabs(3.333)
$16 = 1
(gdb) p (double) fabs(-3.234)
$17 = 1
(gdb) p (double) fabs((double)-3.234)
$18 = 1
(gdb) p ((double(*)(double))fabs)(-3)
$19 = 682945

The code I'm using has included math.h, and the actual code appears to execute correctly, although the same code placed in-line in gdb produces strange results. I could ignore it, but it seems a good learning opportunity.

Community
  • 1
  • 1
ggkmath
  • 4,188
  • 23
  • 72
  • 129

1 Answers1

8

(Ref: http://lists.gnu.org/archive/html/gdb/2009-12/msg00004.html)

gdb is missing the debug information of the cos function, and therefore assume it is an int cos(...) function, so the values are not returned correctly (esp. on x86 as the registers to store floating point return and integer return are different).

This could be worked around by specifying the type:

(gdb) p ((double(*)(double))cos) (1.0)
$18 = 0.54030230586813977
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • Is there no way to provide gdb with the info without the hard to read and hard to type cast? I thought that compiling with '-g' was enough to avoid this kind of issues. – Juan Dec 20 '11 at 03:09
  • If it matters, I compiled with -g and did not include any optimization flags. – ggkmath Dec 20 '11 at 03:19
  • Thanks KennyTM. I thought something like that might be happening, but my experimentation using `(double)` with `fabs()` didn't seem to help (see my latest edit to question above). – ggkmath Dec 20 '11 at 03:20
  • @Juan: It seems you need a debug version of libm, and then use `__cos` instead of `cos` (Ref: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=524424), but I can't get it to work. – kennytm Dec 20 '11 at 03:22
  • @ggkmath: Casting the arguments to `double` doesn't change the signature of the function (this is C, not C++). Casting the function itself `p ((double(*)(double))fabs)(-3.234)` is the only way. – kennytm Dec 20 '11 at 03:25
  • @KennyTM, that code does work. But substitute -3 in place of -3.234 and again it's a funny result (see edited question above for this). Very interesting (I wouldn't have expected this being so difficult for gdb to compute). – ggkmath Dec 20 '11 at 03:35
  • @ggkmath: I believe that's a bug (?) of gdb dealing with function pointers. The `-3` is an integer literal, so it is passed as an integer instead of the floating point registers (xmmN). Casting it to double seems to work. `p ((double(*)(double))fabs)((double)-3)` (very ugly :|) – kennytm Dec 20 '11 at 03:42
  • @KennyTM you're a genius to figure this stuff out. My hat is off to you. Thanks so much! – ggkmath Dec 20 '11 at 04:03