概述
GDB本身不支持将STL容器中的各个元素打印出来,如果使用p命令,只能打印容器的成员。
STLSupport - GDB Wiki一文中列举了三种让GDB支持STL容器的方式。 我试过前两种,第一种最简单,打印的结果也最清楚,然而此方式需要GDB支持Python(7.0)以上版本,而且貌似对GCC编译器也有版本要求,我试过GDB 7.8调试GCC 4.1编译的程序,第一种方式能正常显示vector等容器,但是显示map的时候总是出现如下错误。
Python Exception exceptions.ValueError Cannot find type CarInfoContainer::_Rep_type:
$1 = std::map with 2 elements
由于时间有限,没有深入研究是何原因引起。总之,在现实的大型项目开发团队中,往往开发所用的各种工具如GDB,GCC等版本都偏老(原因你懂的:-)),很可能第一种方式在开发环境中无法使用。本文就举一个简单的例子阐述一下如何用第二种方式显示很复杂的STL容器。
方式二演示
如果容器类型非常简单,比如std::map<int, int>,那么第二种方式可以很简单地用命令“pmap varialbe-name int int”打印出各个元素。但是如果容器很复杂,特别是容器里面还包含容器的时候,输入的命令就很有讲究了,一旦有一点点错误就会无法正常显示结果。以下是一个包含复杂STL容器的例子。
#include <map>
#include <string>
#include <vector>
using namespace std;
struct Car
{
Car (const std::string& model, int32_t price)
: _model(model),
_price(price)
{}
std::string _model;
int32_t _price;
};
typedef std::vector<Car> CarContainer;
typedef std::map<std::string, CarContainer> CarInfoContainer;
int main()
{
CarContainer fordCars;
fordCars.push_back(Car("Focus", 120000));
fordCars.push_back(Car("Mondeo", 200000));
CarContainer vwCars;
vwCars.push_back(Car("Passat", 210000));
CarInfoContainer cars;
cars["US"] = fordCars;
cars["German"] = vwCars;
return 0;
}
当cars map插入两个元素之后,如何用GDB打印其中的内容呢?又如何更进一步,通过map的value type而不是fordCars变量打印出fordCars vector中包含的元素呢?
方法1:直接输入“pmap cars 'std::string' CarContainer”命令,但是GDB会显示如下结果:
elem[0].left: No symbol "std::string" in current context.
我们的程序是打开“-g”调试命令的,GDB已经有了所有的symbol,为何还无法解析“std::string”呢?原因是"std::string"是未经模板实例化的原始类型,模板实例化是编译时发生的,GDB只能识别运行时的变量类型。那么如何得到"std::string"模板实例化后的真正类型?可以用“