2016-11-16 83 views
4

我想要能够使用GDB从STL容器获取地址并打印单个对。C++,STL,GDB:无法评估函数可能内联

IE:鉴于以下玩具程序:

#include <map> 

int main() 
{ 
    std::map<int,int> amap; 
    amap.insert(std::make_pair(1,2)); 

} 

当我试图(通过例如对amap.begin()),我去检查地图中的单个元素:

“无法评估功能 - 可能内置“

删除优化并启用完全调试模式,即(-O0和-g3)不起作用。

为什么会发生这种情况,我该如何解决它?

回答

8

这是因为amap.begin()在结果二进制文件中不存在。这就是C++模板的工作原理:如果您不使用或显式实例化某种模板方法,则不会在生成的二进制文件中生成该模板。

如果你确实想从gdb调用amap.begin()你必须实例化它。做到这一点的方法之一是实例化的std::map所有方法:

#include <map> 

template class std::map<int,int>; 

int main() 
{ 
    std::map<int,int> amap; 
    amap.insert(std::make_pair(1,2)); 
} 

GDB会话:

(gdb) p amap.begin() 
$1 = {first = 1, second = 2} 
+0

这是非常感谢!你能否提供更多的见解,当编译器看到'template class std :: map '时会发生什么情况,即什么使得它实例化类的所有成员?此外,虽然这在源代码可用的情况下仍然有效,但您如何处理调试符号但不是源代码的情况?在这种情况下,建议为什么要检查和调试stl容器? – SFD

+0

'template class std :: map ' - 此语句强制类模板明确实例化,请参阅http://en.cppreference.com/w/cpp/language/class_template。如果您没有源代码,则可以使用Python漂亮打印机(https://sourceware.org/gdb/wiki/STLSupport),它们可能已经安装在您的发行版中。 – ks1322

1

@ ks1322有正确的答案。以下是一些可能在未来有用的附加信息。

只有构造上的std ::地图的析构函数和插入方法是在debuginfo软:

(gdb) info functions std::map 
All functions matching regular expression "std::map": 

File /usr/include/c++/6/bits/stl_map.h: 
std::pair<std::_Rb_tree_iterator<std::pair<int const, int> >, bool> std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::insert<std::pair<int, int>, void>(std::pair<int, int>&&); 
void std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::map(); 
void std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::~map(); 

不过,我们可以调用的大小和空的方法:

(gdb) p amap.size() 
$1 = 1 
(gdb) p amap.empty() 
$2 = false 

这是因为gdb有一些名为xmethods的东西,一种用于调用模型函数的python API,用于与未实例化的函数完全相同的工作。可以找到libstdC++ xmethods here。如果我们禁用它们,则出现相同的错误消息:

(gdb) disable xmethod 
(gdb) p amap.size() 
Cannot evaluate function -- may be inlined 
(gdb) p amap.empty() 
Cannot evaluate function -- may be inlined 
(gdb)