GDB漂亮打印机子类信息

时间:2019-02-15 21:55:21

标签: c++ visual-studio-code gdb clion

我使用Clion IDE和VS Code进行C ++开发和调试,但我发现有所不同,这使我发疯。如果我有一个指向子类的指针向量,则Clion会向我显示子类的类型,而VS Code则没有。这是我可以重现效果的最简单的代码:

#include <iostream>
#include <memory>
#include <vector>
#include <string>

class A {
protected:
    int x;
public:
    A(int x) : x(x) {}

    virtual std::string to_str() { return std::to_string(x); }
};

class B : public A {
    int y;
public:
    B(int x, int y) : A(x), y(y) {}

    std::string to_str() override { return std::to_string(x) + '_' + std::to_string(y); }
};

class C : public A {
    std::string z;
public:
    C(int x, std::string z) : A(x), z(z) {}

    std::string to_str() override { return std::to_string(x) + '_' + z; }
};

int main() {
    std::vector<std::shared_ptr<A>> v;
    v.push_back(std::make_shared<B>(2, 3));
    v.push_back(std::make_shared<C>(4,"5"));

    for(auto &elem : v) {
        std::cout << elem->to_str() << std::endl;
    }

    return 0;
}

没有虚拟函数,没有有关子类的信息。 Clion和VS Code都使用相同的编译器和gdb。 在for内部放置一个断点并在gdb控制台中执行:
p *elem.get()我得到$1 = {_vptr.A = 0x40fc70 <vtable for B+16>, x = 2},但是在Clion中我得到$1 = (B) {<A> = {_vptr.A = 0x40fc70 <vtable for B+16>, x = 2}, y = 3}

列出GDB的配置没有什么区别(相同的gdbinit),也列出漂亮的打印机有一些区别,但没有什么引人注目。

我的猜测是Clion添加了特殊的打印机,但是如果我关闭库渲染器,结果将是相同的。我也在Windows(mingw64 GCC 8.2)和Linux(GCC 7.3)上尝试过,结果相同。

我检查了GDB漂亮打印机文档,但是它不是很有用,所以我没有尝试编写它。 有专门的漂亮打印机显示子类类型和成员吗?

1 个答案:

答案 0 :(得分:0)

为了显示对象的实际类型,CLion启用了GDB的print object设置,这在GDB手册中描述为:

set print object
set print object on
     

在显示指向对象的指针时,请使用虚函数表确定对象的实际(派生)类型,而不是声明的类型。请注意,虚拟功能表是必需的-此功能仅适用于具有运行时类型标识的对象;该对象的声明类型中的单个虚拟方法就足够了。

使用GDB启动调试会话时,将启用此行为,除了在CLion中的GDB控制台视图中,无法禁用它:

(gdb) set print object off