Question

I wonder why evaluate function doesn't work in gdb? In my source file I include, when debugging in gdb, these examples are wrong evaluations.

(gdb) p pow(3,2)

$10 = 1

(gdb) p pow(3,3)

$11 = 1

(gdb) p sqrt(9)

$12 = 0
Was it helpful?

Solution

My guess is that the compiler and linker does some magic with those particular functions. Most likely to increase performance.

If you absolutely need pow() to be available in gdb then you can create your own wrapper function:

double mypow(double a, double b)
{
    return pow(a,b);
}

Maybe also wrap it into a #ifdef DEBUG or something to not clutter the final binary.

BTW, you will notice that other library functions can be called (and their return value printed), for instance:

(gdb) print printf("hello world")
$4 = 11

OTHER TIPS

You need to tell gdb that it will find the return value in the floating point registers, not the normal ones, in addition to give the parameters the right types.

I.e.:

(gdb) p ((double(*)())pow)(2.,2.)

$1 = 4

The syntax for calling a function in gdb is

call pow(3,2)

Type

help call

at the gdb prompt for more information.

Actually, at least on my LINUX implementation of gcc, many of the math functions are replaced with variants specific to the types of their arguments via some fancy substitutions pulled in by math.h and bits/mathcalls.h (included from within math.h). As a consequence, functions like pow and exp are called instead as __pow or *__GI___exp (your results may vary depending on the types of the arguments and perhaps the particular version).

To identify what exactly the function is that is linked in to my code I put a break at a line where just that function is called, e.g. have a line in my code with b=exp(c);. Then I run in gdb up till that break point and then use the "step" command to enter the call from that line. Then I can use the "where" command to identify the name of the called routine. In my case that was *__GI___exp.

There are probably cleverer ways to get this information, however, I was not able to find the right name just by running the preprocessor alone (the -E option) or by looking at the assembly code generated (-s).

pow is defined as a macro , not a function. The call in gdb can only call functions in your program or in shared library. So, the call to pow in gdb should failed.

  (gdb) p pow(3,2)
  No symbol "pow" in current context.

here is the gcc generated binary code of source calling pow (int, int):

  (gdb) list
  1       int main() {
  2       int a=pow(3,2);
  3       printf("hello:%d\n", a);
  4       }
  (gdb) x/16i main
     0x4004f4 <main>:     push   %rbp
     0x4004f5 <main+1>:   mov    %rsp,%rbp
     0x4004f8 <main+4>:   sub    $0x10,%rsp
     0x4004fc <main+8>:   movl   $0x9,-0x4(%rbp)
  => 0x400503 <main+15>:  mov    -0x4(%rbp),%eax
     0x400506 <main+18>:  mov    %eax,%esi
     0x400508 <main+20>:  mov    $0x40060c,%edi
     0x40050d <main+25>:  mov    $0x0,%eax
     0x400512 <main+30>:  callq  0x4003f0 <printf@plt>
     0x400517 <main+35>:  leaveq
     0x400518 <main+36>:  retq
     0x400519:    nop
     0x40051a:    nop
     0x40051b:    nop
     0x40051c:    nop
     0x40051d:    nop

here is the gcc generated binary code of source calling pow (float, float):

  (gdb) list
  1       int main() {
  2       double a=pow(0.3, 0.2);
  3       printf("hello:%f\n", a);
  4       }
  (gdb) x/16i main
     0x4004f4 <main>:     push   %rbp
     0x4004f5 <main+1>:   mov    %rsp,%rbp
     0x4004f8 <main+4>:   sub    $0x10,%rsp
     0x4004fc <main+8>:   movabs $0x3fe926eff16629a5,%rax
     0x400506 <main+18>:  mov    %rax,-0x8(%rbp)
     0x40050a <main+22>:  movsd  -0x8(%rbp),%xmm0
     0x40050f <main+27>:  mov    $0x40060c,%edi
     0x400514 <main+32>:  mov    $0x1,%eax
     0x400519 <main+37>:  callq  0x4003f0 <printf@plt>
     0x40051e <main+42>:  leaveq
     0x40051f <main+43>:  retq
NAME
   pow, powf, powl - power functions

SYNOPSIS
   #include <math.h>

   double pow(double x, double y);

You shouldn't pass an int in the place of a double

 call pow( 3. , 2. )

Also, passing a single argument is not enough, you need two arguments just like the function expects

 wrong: call pow ( 3. )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top