【发布时间】:2010-11-24 04:38:56
【问题描述】:
我想知道为什么评估函数在 gdb 中不起作用?在我包含的源文件中,在 gdb 中调试时,这些示例是错误的评估。
(gdb) p pow(3,2)
$10 = 1
(gdb) p pow(3,3)
$11 = 1
(gdb) p sqrt(9)
$12 = 0
【问题讨论】:
标签: function gdb evaluation
我想知道为什么评估函数在 gdb 中不起作用?在我包含的源文件中,在 gdb 中调试时,这些示例是错误的评估。
(gdb) p pow(3,2)
$10 = 1
(gdb) p pow(3,3)
$11 = 1
(gdb) p sqrt(9)
$12 = 0
【问题讨论】:
标签: function gdb evaluation
你需要告诉gdb它会在浮点寄存器中找到返回值,而不是普通的,除了给参数正确的类型。
即:
(gdb) p ((double(*)())pow)(2.,2.)
$1 = 4
【讨论】:
$1 = 2的值
gdb中调用函数的语法是
call pow(3,2)
键入
help call
在 gdb 提示符下获取更多信息。
【讨论】:
我的猜测是编译器和链接器对这些特定功能做了一些魔术。最有可能提高性能。
如果您绝对需要 pow() 在 gdb 中可用,那么您可以创建自己的包装函数:
double mypow(double a, double b)
{
return pow(a,b);
}
也许还可以将其包装成 #ifdef DEBUG 或其他东西,以免最终二进制文件混乱。
顺便说一句,您会注意到可以调用其他库函数(并打印它们的返回值),例如:
(gdb) print printf("hello world")
$4 = 11
【讨论】:
实际上,至少在我的 gcc 的 LINUX 实现中,许多数学函数通过 math.h 和 bits/mathcalls.h 引入的一些花哨的替换替换为特定于其参数类型的变体(包含在数学.h)。因此,像 pow 和 exp 这样的函数被称为 __pow 或 *__GI___exp (您的结果可能会因参数类型和特定版本而异)。
为了确定链接到我的代码的函数到底是什么,我在只调用该函数的行处放置了一个中断,例如在我的代码中有一行b=exp(c);。然后我在 gdb 中运行直到那个断点,然后使用“step”命令从该行输入调用。然后我可以使用“where”命令来识别被调用例程的名称。在我的例子中是*__GI___exp。
可能有更聪明的方法来获取这些信息,但是,我无法仅通过单独运行预处理器(-E 选项)或查看生成的汇编代码(-s)来找到正确的名称。
【讨论】:
p pow 给了我:$28 = {<text variable, no debug info>} 0x7ffff77ffbd0 <__pow>
NAME
pow, powf, powl - power functions
SYNOPSIS
#include <math.h>
double pow(double x, double y);
你不应该传递一个 int 来代替一个 double
call pow( 3. , 2. )
另外,传递一个参数是不够的,你需要两个参数,就像函数期望的那样
wrong: call pow ( 3. )
【讨论】: