如何评估 GDB 中的函数?

Posted

技术标签:

【中文标题】如何评估 GDB 中的函数?【英文标题】:How to evaluate functions in GDB? 【发布时间】: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

【问题讨论】:

【参考方案1】:

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

即:

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

$1 = 4

【讨论】:

奇怪的是我得到了$1 = 2的值 您好!我是个白痴,一直在努力弄清楚 double() 到底是什么意思?我认为这意味着一个函数指针可以“返回双指针,并采用 void args”。所以我尝试重新转换为 ((double)())pow)(2.,2.) - 失败了!为什么? @BebeCarabina 我感到你很沮丧:我希望避免这种类型转换引起的严重头部创伤。我在How to evaluate functions in GDB without painful typecasting?发了一个相关的问题,看看有没有解决办法。【参考方案2】:

gdb中调用函数的语法是

call pow(3,2)

键入

help call

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

【讨论】:

谢谢!但是调用仍然不能正常工作 (gdb) call sqrt(9) $14 = 0 (gdb) call pow(3,3) $15 = 1 print 也会调用函数。事实上,我认为唯一的区别是调用 void 函数时调用不会使输出混乱【参考方案3】:

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

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

double mypow(double a, double b)

    return pow(a,b);

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

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

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

【讨论】:

anon 下面给出了正确答案 @mattypiper “下面由 anon 给出”需要该评论中的链接。我想你打算指向anon's answer。【参考方案4】:

实际上,至少在我的 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>【参考方案5】:
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. )

【讨论】:

实际上,传递整数工作正常。不确定这是否只是巧合,但是用整数调用 mypow (请参阅我的答案)会产生正确的结果。调用 pow(2.0,2.0) 时我没有从 gdb 得到任何输出,但是当使用任何数字调用 mypow() 时我会这样做

以上是关于如何评估 GDB 中的函数?的主要内容,如果未能解决你的问题,请参考以下文章

使用clang时在gdb中评估libc ++的方法

在 STM32H7 上使用 GDB 进行远程调试,无需 PC 连接到评估板

seq如何评估Haskell中的无限列表?

如何评估 MySQL 存储的_function_ 中的简单数学公式?

在 C 中,我如何评估一个函数中的局部变量,在不同的函数中?

如何将变量传递给评估函数?