如何评估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
用于在gdb调用一个函数的语法是
call pow(3,2)
类型
help call
在获得更多信息gdb提示。
谢谢!但呼叫仍无法正常工作 (GDB)调用的sqrt(9) $ 14 = 0 (GDB)调用POW(3,3) $ 15 = 1 – Tim 2009-08-30 20:09:29
打印也将调用函数。实际上,我认为唯一的区别是调用无效函数 – 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.)
时调用不会混乱输出,传入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)来找到正确的名称。
给出我知道这是旧的,但是如果有人来看,这里是:对我来说,它只是做'p pow',它给了我:'$ 28 = {} 0x7ffff77ffbd0 <__pow>' – falstro 2014-03-01 10:35:14
您需要告诉gdb它会在浮点寄存器中找到返回值,而不是普通的,除了给参数提供正确的类型之外。
即:
(GDB)P((双(*)())POW)(2,2。)
$ 1 = 4
这很奇怪我得到'$ 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
正确的答案在下面由anon – mattypiper 2017-10-16 20:06:40