使LLDB重新解释地址作为指向其类型为模板实例化的对象的指针

时间:2016-11-04 13:41:44

标签: c++ templates lldb

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

请参阅此示例代码:

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)

1 个答案:

答案 0 :(得分:3)

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

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

onRowClick: function(row) {
    const systemId = row._id;
    this.context.router.transitionTo(`/system/${systemId}`)
}

然后在main:

typedef X<int> * x_int_ptr;

确保记录,然后在ldb我可以做:

  x_int_ptr bar = (x_int_ptr) &x;