c++ - 使 LLDB 将地址重新解释为指向模板实例化类型的对象的指针

标签 c++ templates lldb

调试时,我在内存中有一个地址,并且知道驻留在该地址的对象的类型,并且我希望调试器显示该对象的该实例。对于不是模板的类型,这可以通过打印命令来完成,但对于模板实例化的类型似乎会失败。

请参阅此示例代码:

template<typename T>
class X
{
public:
    X() {
        printf("a\n");
    }
};

class Y
{
public:
    Y() {
        printf("a\n");
    }
};



int main(void)
{
    X<int> x;
    Y y;

    return 1;
}

当我运行程序时,中断 main 并尝试将随机有效地址解释为指向 X 和 Y 对象的指针,前者失败:

(lldb) p *(Y*)0x0000000100000ee6
(Y) $0 = {}
(lldb) p *(X<int>*)0x0000000100000ee6
warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
error: use of undeclared identifier 'X'
error: expected '(' for function-style cast or type construction
error: expected expression

有什么办法可以在 lldb 中做到这一点吗? (编辑:Mac OS X lldb-360.1.65 和 lldb-310.2.37)

最佳答案

C++ 的调试信息当前并不代表抽象的模板,它仅讨论程序中存在的特定模板实例化。但是 lldb 的表达式命令使用真正的 C++ 解析器 (clang),当解析像您尝试的那样的表达式时,它希望首先将 X 视为抽象模板。由于我们不了解它们,因此我们无法满足 clang 对 X 的类型请求,并且 - 这就是为什么您看到的错误是“未声明的标识符 X”。

您可以通过为要以这种方式转换的指针类型创建 typedef 来解决此问题。这不是很令人满意,因为你必须预先完成它,并且你必须在代码中的某个地方使用 typedef,因为 - 为了保持调试信息的大小易于管理 - clang 不会为不适合的类型发出调试信息用过的。但它确实有效,例如我添加到您的示例代码:

typedef X<int> * x_int_ptr;

然后在 main 中:

  x_int_ptr bar = (x_int_ptr) &x;

为了确保它被记录,然后在ldb中我可以这样做:

(lldb) expr *((x_int_ptr) 0x00007fff5fbff798)
(X<int>) $1 = {}

关于c++ - 使 LLDB 将地址重新解释为指向模板实例化类型的对象的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40424192/

相关文章:

c++ - 在 C++ 中按字母顺序对对象列表进行排序

c++ - 为什么新的 Visual Studio 运行时不是 Windows 的一部分

C++访问 vector 中的对元素

ios - 由于 LLDB,Xcode 在尝试运行项目时崩溃

iphone - po 对象导致错误 : cannot find interface declaration for '$__lldb_objc_class'

c++ - Q消息框;按钮布局

c++ - 如何任意排序元组的类型?

c++ - 为什么模板化的派生类可以在 gcc 上访问其基私有(private)成员?

c++ - 如何使用指向泛型模板类的指针来访问依赖于模板参数类型的成员函数

Swift LLBD 消息 "<Unable to determine byte size.>"