2

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

默认情况下,std::vector "data_" 总是显示为线性向量。我希望我的提供者创建一个视图层次结构。在此示例中,第一级将是子行,每行扩展为列值列表。类似于查看静态二维数组(即 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 个子级的第一级是“行”,其中包含行中前导元素的摘要字符串。这个想法是获得矩阵数据的二维视图。然后当一行被扩展时,它会被视为一个列值的数组。

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?

4

2 回答 2

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(就像我们在内部做的那样),这是你唯一的方法

于 2014-03-21T02:42:30.127 回答
0

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

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

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

于 2020-10-21T19:17:30.817 回答