如何评估GDB中的函数?

问题描述:

我不知道为什么评估函数在gdb中不起作用?在我的源文件中,当在gdb中调试时,这些示例是错误的评估。如何评估GDB中的函数?

(gdb) p pow(3,2) 

$10 = 1 

(gdb) p pow(3,3) 

$11 = 1 

(gdb) p sqrt(9) 

$12 = 0 

我的猜测是编译器和链接器对这些特定的函数做了一些魔术。最有可能提高性能。

如果您确实需要pow()是在gdb可用,那么你可以创建自己的包装函数:

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

也许也把它包装成一个#ifdef DEBUG什么不杂乱最终的二进制。

BTW,你会发现其他的库函数可以调用(和它们的返回值打印),例如:

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

正确的答案在下面由anon – mattypiper 2017-10-16 20:06:40

用于在gdb调用一个函数的语法是

call pow(3,2) 

类型

help call 

在获得更多信息gdb提示。

+0

谢谢!但呼叫仍无法正常工作 (GDB)调用的sqrt(9) $ 14 = 0 (GDB)调用POW(3,3) $ 15 = 1 – Tim 2009-08-30 20:09:29

+1

打印也将调用函数。实际上,我认为唯一的区别是调用无效函数 – 2009-08-30 20:21:30

NAME 
    pow, powf, powl - power functions 

SYNOPSIS 
    #include <math.h> 

    double pow(double x, double y); 

在双

call pow(3. , 2.) 

另外的地方你不应该传递一个int,传递一个参数是不够的,你需要两个参数,就像函数需要

wrong: call pow (3.) 
+1

时调用不会混乱输出,传入int正常工作。不知道这是不是巧合,但用整数调用mypow(请参阅我的答案)会产生正确的结果。调用pow(2.0,2.0)时,我没有从gdb获得输出,但是我在用任何数字调用mypow()时做了 – 2009-08-30 20:20:06

其实,在我的Linux实现的gcc至少,很多的数学函数被math.h和bits/mathcalls.h(包含在math.h中)引入的一些花式替换替换为特定于它们参数类型的变体。因此,像pow和exp这样的函数被调用为__pow*__GI___exp(您的结果可能因参数的类型以及可能的特定版本而异)。

为了确定链接到我的代码的函数是什么,我在只调用该函数的那一行放了一个中断,例如,在我的代码中有一行b=exp(c);。然后我在gdb中运行,直到该断点,然后使用“step”命令从该行输入呼叫。然后我可以使用“where”命令来标识被调用例程的名称。在我的情况下,这是*__GI___exp

可能有更聪明的方法来获取这些信息,但是,我无法通过单独运行预处理器(-E选项)或查看生成的汇编代码(-s)来找到正确的名称。

+2

给出我知道这是旧的,但是如果有人来看,这里是:对我来说,它只是做'p pow',它给了我:'$ 28 = {} 0x7ffff77ffbd0 <__pow>' – falstro 2014-03-01 10:35:14

您需要告诉gdb它会在浮点寄存器中找到返回值,而不是普通的,除了给参数提供正确的类型之外。

即:

(GDB)P((双(*)())POW)(2,2。)

$ 1 = 4

+0

这很奇怪我得到'$ 1 = 2' – daj 2015-06-27 15:43:52

POW被定义为一个宏,而不是一个函数。 gdb中的调用只能调用程序或共享库中的函数。所以,在gdb中调用pow应该失败。

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

这里是源调用POW(INT,INT)的GCC生成的二进制代码:

(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 <[email protected]> 
    0x400517 <main+35>: leaveq 
    0x400518 <main+36>: retq 
    0x400519: nop 
    0x40051a: nop 
    0x40051b: nop 
    0x40051c: nop 
    0x40051d: nop 

这里是gcc的生成源的二进制代码调用POW(浮点,浮点):

(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 <[email protected]> 
    0x40051e <main+42>: leaveq 
    0x40051f <main+43>: retq