37

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

(gdb) p pow(3,2)

$10 = 1

(gdb) p pow(3,3)

$11 = 1

(gdb) p sqrt(9)

$12 = 0
4

5 回答 5

30

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

IE:

(gdb) p ((double(*)())pow)(2.,2.)

$1 = 4

于 2012-11-15T13:30:38.877 回答
28

在 gdb 中调用函数的语法是

call pow(3,2)

类型

help call

在 gdb 提示符下获取更多信息。

于 2009-08-30T20:03:06.317 回答
20

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

如果您绝对需要pow()在 gdb 中可用,那么您可以创建自己的包装函数:

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

也许也可以将它包装成 a#ifdef DEBUG或其他东西,以免使最终的二进制文件混乱。

顺便说一句,您会注意到可以调用其他库函数(并打印它们的返回值),例如:

(gdb) print printf("hello world")
$4 = 11
于 2009-08-30T20:17:03.340 回答
5

实际上,至少在我的 gcc 的 LINUX 实现中,许多数学函数通过 math.h 和 bits/mathcalls.h (包含在 math.h )。因此,像 pow 和 exp 这样的函数被称为__powor *__GI___exp(您的结果可能会因参数的类型以及特定的版本而异)。

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

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

于 2012-01-10T14:53:52.970 回答
1
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. )
于 2009-08-30T20:16:21.767 回答