首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调试器内部调用标准数学函数失败吗?

调试器内部调用标准数学函数失败吗?
EN

Stack Overflow用户
提问于 2016-10-21 03:11:17
回答 2查看 517关注 0票数 2

我试图在调试器中调用自己的函数和标准函数:

代码语言:javascript
复制
#include<stdlib.h>
#include<math.h>
#include<stdio.h>
int i=3;
void f(){
  ++i;
  printf("%d\n",i);
}
int main(){
  ++i;
  int j=i+2;
  double d=cos(0.0);
  printf("%f\n",d);
  return 0;
}

编译这个程序并运行,它将像我所期望的那样打印"1.000000“。在gdb,我试过:

代码语言:javascript
复制
(gdb) b main
Breakpoint 1 at 0x40055b: file x.c, line 10.
(gdb) r
Starting program: /home/x/a.out 

Breakpoint 1, main () at x.c:10
10    ++i;
(gdb) call f()
4
(gdb) call f()
5
(gdb) call cos(0.0)
No symbol "cos" in current context.  # WHY?????
(gdb) call printf("%d\n",i)
5
$1 = 2
(gdb) call putchar('a')
$2 = 97

为什么gdb能找到符号?我认为"-g“选项将为我的程序和标准库带来调试信息,对吗?还是我必须为标准库安装额外的调试/源代码包?我上的是ubuntu16.04

非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-21 04:15:11

尽管看上去很直接,但gdb的这一部分运行良好。因此,我的第一本能是,我们处于某种GIGO的情况-- gdb异常容易受到编译器和内核的敌人行动的影响--需要进行一些调查。

你不会说你是在使用C还是C++。

在C++中,我可以看到没有为cos发出任何调试器,并且调用是完全优化的。您可以通过运行nm并注意到cos不显示为一个未定义的符号来检查这一点;或者只需注意到该程序在没有-lm的情况下链接就很好。

我对C++的理论是,这是因为作用域中有一个constexpr版本的cos (我在预处理的输出中看到了它,但我并没有真正验证),所以g++优化了整个调用。

对于C,默认情况下我会看到同样的情况。然而,我可以通过把cos传递给gcc来给-fno-builtin-cos打电话。但是,哈哈,它还没有出现在第一次亮相!

在我看来,这就像是gcc的窃听器。通常,库不需要调试器就可以访问程序使用的库中的类型或函数。

您还可以注意到,通过打印函数本身,正在发生一些奇怪的事情:

代码语言:javascript
复制
(gdb) p cos
$1 = {<text gnu-indirect-function variable, no debug info>} 0x7ffff7aebc50 <cos>

这是双重的坏消息,因为"GNU间接“函数是神奇的生物,gdb并不总是正确理解。特别是,我认为即使安装了调试器,也无法从调试器调用它们。

实际上,我唯一能做的就是在程序中获取cos的地址,然后通过指针调用,比如:

代码语言:javascript
复制
mumble *my_cos = &cos;
...
(gdb) print my_cos(0.0)

嗯,这不是完全正确。我也可以这样做:

代码语言:javascript
复制
(gdb) info func cos@plt
All functions matching regular expression "cos@plt":

Non-debugging symbols:
0x0000000000400500  cos@plt
(gdb) p ((double(*)(double))0x0000000000400500)(0.0)
$6 = 1

这样就避免了GNU的间接问题。然而,这是相当不愉快的。

票数 4
EN

Stack Overflow用户

发布于 2016-10-21 07:50:49

  • cos函数是用libm实现的,而不是libc实现的。你和-lm有联系吗?
  • 编译器优化常量表达式。没有理由在运行时计算cos(0)。因此,不需要包含cos函数,也不需要链接数学库。对libm的引用将从您的可执行文件中删除(您可以使用read亲自或类似的工具进行验证),因此gdb对cos (或数学库中的任何其他函数)一无所知。
  • 正如Tromey解释的那样,一个可能的解决办法是禁用gcc的内置功能。在此之后,我可以从gdb调用cos (如:print(1.0))。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40167748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档