无法在调试器中调用标准数学函数?
Failed to call standard math function inside debugger?
我尝试在调试器中调用我自己的函数和标准函数:
#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
= 2
(gdb) call putchar('a')
= 97
为什么gdb连符号都找不到?我想“-g”选项会为我的程序和标准库带来调试信息,对吧?或者我是否必须为标准库的 debugging/source 代码安装额外的包?我在 ubuntu16.04
非常感谢。
尽管直接出现,但 gdb 的这一部分运行良好。所以我的第一直觉是我们处于某种 GIGO 情况——gdb 异常容易受到编译器和内核的敌对行为的影响——需要进行一些调查。
你不说你用的是C还是C++。
在 C++ 中,我可以看到没有为 cos
发出调试信息,调用已完全优化掉。您可以通过 运行 nm
进行检查,并注意 cos
并未显示为未定义的符号;或者只是注意到这个程序在没有 -lm
.
的情况下链接得很好
我对 C++ 的理论是,发生这种情况是因为范围内有 cos
的 constexpr
版本(我在预处理输出中看到它,但我没有尝试真正验证),因此 g++ 优化了整个调用。
对于 C,默认情况下我看到相同的东西。但是,我可以通过将 -fno-builtin-cos
传递给 gcc 来调用 cos
。但是,哈哈,它仍然没有在调试信息中!
对我来说这似乎是一个 gcc 错误。通常,您不需要库的 debuginfo 就可以访问您的程序使用的库中的类型或函数。
您还可以通过尝试打印函数本身来注意到发生了一些奇怪的事情:
(gdb) p cos
= {<text gnu-indirect-function variable, no debug info>} 0x7ffff7aebc50 <cos>
这是一个双重坏消息,因为 "GNU indirect" 函数是神奇的生物,gdb 并不总能正确理解它。特别是我不认为它们可以从调试器调用,即使安装了 debuginfo。
事实上,我唯一能做的就是在程序中获取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)
= 1
这避免了 GNU 间接的东西。不过,挺不爽的。
- cos 函数是在 libm 中实现的,而不是 libc。你甚至 link 使用 -lm?
- 编译器优化掉常量表达式。没有理由在 运行 时间计算 cos(0)。所以不需要包含 cos 函数,也没有理由 linked 数学库。对 libm 的引用已从您的可执行文件中删除(您可以使用 readelf 或类似工具进行验证),因此 gdb 对 cos(或数学库中的任何其他函数)一无所知。
- 正如 Tom Tromey 所解释的,一种可能的解决方法是禁用 gcc 的内置函数。之后我可以从 gdb 调用 cos(比如 this:print cos(1.0))。
我尝试在调试器中调用我自己的函数和标准函数:
#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
= 2
(gdb) call putchar('a')
= 97
为什么gdb连符号都找不到?我想“-g”选项会为我的程序和标准库带来调试信息,对吧?或者我是否必须为标准库的 debugging/source 代码安装额外的包?我在 ubuntu16.04
非常感谢。
尽管直接出现,但 gdb 的这一部分运行良好。所以我的第一直觉是我们处于某种 GIGO 情况——gdb 异常容易受到编译器和内核的敌对行为的影响——需要进行一些调查。
你不说你用的是C还是C++。
在 C++ 中,我可以看到没有为 cos
发出调试信息,调用已完全优化掉。您可以通过 运行 nm
进行检查,并注意 cos
并未显示为未定义的符号;或者只是注意到这个程序在没有 -lm
.
我对 C++ 的理论是,发生这种情况是因为范围内有 cos
的 constexpr
版本(我在预处理输出中看到它,但我没有尝试真正验证),因此 g++ 优化了整个调用。
对于 C,默认情况下我看到相同的东西。但是,我可以通过将 -fno-builtin-cos
传递给 gcc 来调用 cos
。但是,哈哈,它仍然没有在调试信息中!
对我来说这似乎是一个 gcc 错误。通常,您不需要库的 debuginfo 就可以访问您的程序使用的库中的类型或函数。
您还可以通过尝试打印函数本身来注意到发生了一些奇怪的事情:
(gdb) p cos
= {<text gnu-indirect-function variable, no debug info>} 0x7ffff7aebc50 <cos>
这是一个双重坏消息,因为 "GNU indirect" 函数是神奇的生物,gdb 并不总能正确理解它。特别是我不认为它们可以从调试器调用,即使安装了 debuginfo。
事实上,我唯一能做的就是在程序中获取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)
= 1
这避免了 GNU 间接的东西。不过,挺不爽的。
- cos 函数是在 libm 中实现的,而不是 libc。你甚至 link 使用 -lm?
- 编译器优化掉常量表达式。没有理由在 运行 时间计算 cos(0)。所以不需要包含 cos 函数,也没有理由 linked 数学库。对 libm 的引用已从您的可执行文件中删除(您可以使用 readelf 或类似工具进行验证),因此 gdb 对 cos(或数学库中的任何其他函数)一无所知。
- 正如 Tom Tromey 所解释的,一种可能的解决方法是禁用 gcc 的内置函数。之后我可以从 gdb 调用 cos(比如 this:print cos(1.0))。