我试图在调试器中调用自己的函数和标准函数:
#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,我试过:
(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
非常感谢。
发布于 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的窃听器。通常,库不需要调试器就可以访问程序使用的库中的类型或函数。
您还可以注意到,通过打印函数本身,正在发生一些奇怪的事情:
(gdb) p cos
$1 = {<text gnu-indirect-function variable, no debug info>} 0x7ffff7aebc50 <cos>这是双重的坏消息,因为"GNU间接“函数是神奇的生物,gdb并不总是正确理解。特别是,我认为即使安装了调试器,也无法从调试器调用它们。
实际上,我唯一能做的就是在程序中获取cos的地址,然后通过指针调用,比如:
mumble *my_cos = &cos;
...
(gdb) print my_cos(0.0)嗯,这不是完全正确。我也可以这样做:
(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的间接问题。然而,这是相当不愉快的。
发布于 2016-10-21 07:50:49
https://stackoverflow.com/questions/40167748
复制相似问题