GDB调试STL复杂容器

本文介绍了如何在GDB中有效地调试STL容器,尤其是面对GDB不直接支持打印容器元素的问题。通过尝试GDB Wiki推荐的前两种方法,特别是需要GDB 7.0以上版本和Python支持的第一种方式,可以清晰地查看vector和map等容器内容。但在较低版本的GDB和GCC中可能会遇到问题,例如调试GCC 4.1编译的程序时,调试map会出现错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

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"模板实例化后的真正类型?可以用“
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值