我想知道为什么评估函数在gdb中不起作用?在我的源文件中包含,当在gdb中调试时,这些示例是错误的评估。
(gdb) p pow(3,2)
$10 = 1
(gdb) p pow(3,3)
$11 = 1
(gdb) p sqrt(9)
$12 = 0
答案 0 :(得分:19)
除了给参数提供正确的类型之外,你需要告诉gdb它会在浮点寄存器中找到返回值,而不是正常寄存器中的返回值。
即:
(gdb)p((double(*)())pow)(2.,2。)
$ 1 = 4
答案 1 :(得分:18)
我的猜测是编译器和链接器对这些特定函数做了一些魔术。最有可能提高性能。
如果您绝对需要在{g}中使用pow()
,那么您可以创建自己的包装函数:
double mypow(double a, double b)
{
return pow(a,b);
}
也许还将它包装成#ifdef DEBUG
或其他东西,以免弄乱最终的二进制文件。
(gdb) print printf("hello world")
$4 = 11
答案 2 :(得分:17)
在gdb中调用函数的语法是
call pow(3,2)
输入
help call
在gdb提示符下获取更多信息。
答案 3 :(得分:4)
实际上,至少在我的gcc的LINUX实现中,许多数学函数被替换为特定于其参数类型的变体,通过math.h和bits / mathcalls.h引入的一些奇特的替换(包含在内部) math.h中)。因此,像pow和exp这样的函数被称为__pow
或*__GI___exp
(您的结果可能会因参数的类型和特定版本而异)。
为了确定与我的代码链接的功能究竟是什么,我在一个只调用该函数的行中放置了一个中断,例如:我的代码中有一行b=exp(c);
。然后我在gdb中运行直到该断点,然后使用“step”命令从该行输入调用。然后我可以使用“where”命令来识别被调用例程的名称。在我的情况下是*__GI___exp
。
可能有更聪明的方法来获取此信息,但是,我无法仅通过单独运行预处理器(-E选项)或查看生成的汇编代码(-s)来找到正确的名称。
答案 4 :(得分:1)
pow定义为宏,而不是函数。 gdb中的调用只能调用程序或共享库中的函数。因此,在gdb中调用pow应该会失败。
(gdb) p pow(3,2)
No symbol "pow" in current context.
这里是gcc生成的源代码调用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
这里是源代码调用pow(float,float)的gcc生成的二进制代码:
(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
答案 5 :(得分:0)
NAME
pow, powf, powl - power functions
SYNOPSIS
#include <math.h>
double pow(double x, double y);
你不应该在双重
的位置传递一个int call pow( 3. , 2. )
另外,传递一个参数是不够的,你需要两个参数就像函数期望的那样
wrong: call pow ( 3. )