GDB 漂亮的打印机子类信息

GDB pretty printer subclass info

我使用 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() 我得到 = {_vptr.A = 0x40fc70 <vtable for B+16>, x = 2} 但是在 Clion 我得到 = (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 pretty-printer 文档,但它不是很有用,所以我没有尝试编写一个。 是否有专门的漂亮打印机来显示子类类型和成员?

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

set print object
set print object on

When displaying a pointer to an object, identify the actual (derived) type of the object rather than the declared type, using the virtual function table. Note that the virtual function table is required — this feature can only work for objects that have run-time type identification; a single virtual method in the object’s declared type is sufficient.

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

(gdb) set print object off