情况:
我有一个用c ++ 11编写的autotools项目,我可以用clang 3.3 / 3.4或gcc 4.8编译。 我的autotools项目构建了一个共享库和一个可执行文件。
如果我使用gcc 4.8并调试可执行文件,我可以添加一个观察点来检查共享库中存在的全局变量的值。
当我使用QT创建者或CDT或其他调试器时,或者甚至当我查看gdb 7.6.2的输出时:当使用clang编译时,它在调试输出中显示“没有这样的值”,而使用gcc我可以检查调试器中全局变量的值。
我基本上将相同的开关发送到gcc和clang,-O0 -g。使用这两个编译器,我可以检查并查看堆栈上的值,但只需使用clang 3.3或clang 3.4生成的输出,我就无法检查共享库中存在的全局变量。我的环境是Ubuntu 12.04,带有自编译的clang和gdb。
我已经确认我正在检查的全局符号确实存在于任一编译器生成的共享库中。
是否有一些特定的编译器开关或我应该发送到clang的东西,以便能够调试共享库中的符号?或者这可能是clang的错误?
答案 0 :(得分:0)
根据我的经验,clang 3.3搞砸了调试信息。让我们考虑一个简单的程序:
#include <string>
int main()
{
std::string s("foo");
s.size();
return 0;
}
编译:
$ clang++ -O0 -ggdb -c t.cpp -o t.o
现在让我们检查一下调试符号:
$ objdump --dwarf=info t.o | grep -A2 -B1 _Rep
<3><3c3>: Abbrev Number: 29 (DW_TAG_structure_type)
<3c4> DW_AT_name : (indirect string, offset: 0x2ff): _Rep
<3c8> DW_AT_declaration : 1
<3><3c8>: Abbrev Number: 28 (DW_TAG_subprogram)
正如您所看到的,_Rep(它是std :: string的一部分)标有DW_AT_declaration属性,这意味着声明了_Rep,但未定义。这就是为什么在使用gdb进行调试时,如果您对上述程序尝试print s
,则会看到No type named std::basic_string<char>::_Rep
。
这就是_Rep
的调试信息的真实含义:
$ objdump --dwarf=info t.o | grep -P -A4 -B1 '\b_Rep\b'
<3><119>: Abbrev Number: 16 (DW_TAG_structure_type)
<11a> DW_AT_name : (indirect string, offset: 0x578): _Rep
<11e> DW_AT_byte_size : 24
<11f> DW_AT_decl_file : 7
<120> DW_AT_decl_line : 155
<4><121>: Abbrev Number: 11 (DW_TAG_inheritance)
我敢打赌你在铿锵声中面对这种或类似的情况。