How to evaluate functions in GDB?

余生长醉 提交于 2019-11-27 12:49:09

问题


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

回答1:


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



回答2:


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




回答3:


The syntax for calling a function in gdb is

call pow(3,2)

Type

help call

at the gdb prompt for more information.




回答4:


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




回答5:


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



回答6:


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


来源:https://stackoverflow.com/questions/1354731/how-to-evaluate-functions-in-gdb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!