如何为std :: vector数据的形状视图编写LLDB合成提供程序

时间:2014-03-20 03:58:48

标签: python c++ vector lldb synthetic

我正在尝试为项目中的类创建LLDB可视化工具。 LLDB文档是......稀疏的。我有一个数组类,它将底层数据存储在std :: vector中,并有一个extent数组来描述形状。它也可以在以后重新塑造。

默认情况下,std :: vector"数据_"始终显示为线性向量。我希望我的提供者创建一个视图层次结构。在此示例中,第一个级别是子行,每行扩展为列值列表。类似于查看静态2D数组(即double [3] [2])。你可以想象将它扩展到N维。

我似乎无法弄清楚如何使用lldb python对象模型将层次结构强加到std :: vector中的线性缓冲区。 似乎没有任何文件记录,我在黑暗中猜测了大约一个星期。这是一个简化的示例数组类,我想为它创建一个可视化工具。

非常感谢任何帮助!

#include <vector>
#include <cassert>

template <typename T>
class myarray {
    int extent_[2];
    std::vector<T> data_;

public:
    myarray(int r, int c, const T* data) {
        extent_[0] = r;
        extent_[1] = c;
        data_.resize(r * c);
        for(size_t i = 0; i < data_.size(); ++i) data_[i] = data[i];
    }

    void reshape(int r, int c) {
        assert(r * c == data_.size());
        extent_[0] = r;
        extent_[1] = c;
    }
};


int main(int argc, const char * argv[])
{
    double initdata[6] = { 0, 1, 2, 3, 4, 5 };
    myarray<double> mydata(3, 2, initdata);

    mydata.reshape(1, 6);

    return 0;
}

根据要求:我想看到的第一个[3] [2]示例的输出可能如下所示。 3个孩子的第一个级别是&#34; rows&#34;,其中包含行中前导元素的摘要字符串。我们的想法是获得矩阵数据的2D视图。然后,当展开一行时,它将被视为一个列值数组。

LLDB潜在合成产出:

mydata
[0]
   [0] = 0 <-- expanded contents
   [1] = 1
[1] = {2, 3} <-- summary string of row contents. First N elements, then ...
[2] = {4, 5}

简单向量的合成提供程序示例实现了get_child_at_index,我在update()方法中确定了count,value_size和value_type:

def get_child_at_index(self,index):
    logger = lldb.formatters.Logger.Logger()
    logger >> "get_child_at_index: " + str(index)
    if index < 0: return None;
    if index >= self.count: return None;
    try:
        offset = index * self.value_size
        return self.data.CreateChildAtOffset('['+str(index)+']',offset,self.value_type)
    except:
        return None

我想如果我能够在调用CreateChildAtOffset时弄清楚如何创建一个SBType来代替value_type,我可以轻松解决这个问题。我想我可以放下任何我喜欢的结构。然而,由于在黑暗中有许多镜头,我无法弄清楚如何成功创建SBType对象。

想法?有谁知道如何从我撰写的字符串创建SBType?

2 个答案:

答案 0 :(得分:1)

我假设您已经查看过:http://lldb.llvm.org/varformats.html

IIUC,您要做的是以更分层的格式显示向量的元素。

这是一项有趣的任务,你可能需要制作自己的数据类型 - 我认为我们目前在公共API中没有得到很多支持。 作为一种解决方法,您当然可以运行一个表达式来生成您关心的结构并保持它 - 但这将会很慢。

在您的示例中,您希望获得的视图到底是什么?这种示例信息实际上可以帮助我们找出更多细节。

编辑:目前LLDB不允许您通过公共API创建新类型。您可以使用表达式解析器来完成自己制作的SBType,如下例所示:

x = lldb.frame.EvaluateExpression("struct foo { int x; }; foo myfoo = {12}; myfoo")
data = lldb.SBData.CreateDataFromSInt32Array(lldb.eByteOrderLittle,8,[24])
x_type = x.GetType()
myOtherFoo = x.CreateValueFromData("myOtherFoo",data,x_type)
print myOtherFoo
OUTPUT: (foo) myOtherFoo = (x = 24)

这将是相当慢的,特别是如果你不缓存你需要的foo类型(从你的例子看来你的模板参数T的T [2]) - 但是直到LLDB有SB API到通过clang创建类型(就像我们在内部做的那样),这是你唯一的方法

答案 1 :(得分:0)

不确定这是否有帮助,但是您可以找到现有的类型

  target = lldb.debugger.GetSelectedTarget()
  type_list = target.FindTypes('base::Value')

如果要使用现有类型创建孩子,这可能会有所帮助。