包含双数组的GDB pretty print自定义类型

2024-04-24 00:02:17 发布

您现在位置:Python中文网/ 问答频道 /正文

尝试将GyDB扩展到GDB,它可以很好地打印下面的C++类:

class Vector {
  double* myElements;
  unsigned int length;
}

其中漂亮的打印输出应该是{0.1, 0.2, 0.3},其中数组myElements的长度是length。你知道吗

在gdb中,我可以简单地执行*myVec.myElements@myVec.length,但是我想创建Python pretty print,它可以执行相同的操作。你知道吗

我目前的尝试如下:

class VectorPrinter:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        length = self.val['length']
        elmts = self.val['myElements']
        result = []
        for i in range(0, length):
            result.append(elmts[i])

        return str(result)


class FailPrinter:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "Value: " + str(self.val.type)

def lookup_type(val):
    if(str(val.type) == 'Vector'):
        return VectorPrinter(val)
    return FailPrinter(val)

gdb.pretty_printers.append(lookup_type)

然而,这只是输出:

$1 = [<gdb.Value object at 0x000000000367d470>, <gdb.Value object at 0x000000000367d4b0>, ...,
 <gdb.Value object at 0x000000000367d8f0>, <gdb.Value object at 0x000000000367d930>]

Tags: selfreturnobjectvaluedeftypevalresult
1条回答
网友
1楼 · 发布于 2024-04-24 00:02:17

当您的类型是某种“类型的数组”时,最好保持to_string方法简单(不处理元素)并且 返回用于检索元素的生成器的children方法,以及display_hint方法。这个display_hint方法必须返回字符串“array”,以指示gdb应该使用children方法来获取元素。你知道吗

to_string方法可以简单到只返回一个简单的字符串,比如“vector”,但是我发现包含向量的大小很有用。你知道吗

我为你们班制作了以下漂亮的打印机

class VectorPrinter:
    def __init__(self, val):
        self.val = val
        self.length = int(val['length'])
        self.mem = self.val['myElements']

    def to_string(self):
        return f"Vector with {self.length} elements"

    def next_element(self):
        for i in range(self.length):
            yield str(i), (self.mem + i).dereference()

    def children(self):
        return self.next_element()

    def display_hint(self):
        return "array"

注意,next_element方法实际上是一个生成器,因为它使用yield而不是return。你知道吗

然而,当我尝试使用这个漂亮的打印机时,每个元素都被打印成Value: double,。问题是因为FailPrinter。注册pretty printers的方式意味着,除了Vector类之外,其他所有都是使用FailPrinter打印的,包括每个单独的元素。你并不真的需要(或想要)一个“失败”的打印机。你知道吗

因此,只需使用我提供的类并注册它

def lookup_type(val):
    if(str(val.type) == 'Vector'):
        return VectorPrinter(val)

gdb.pretty_printers.append(lookup_type)

让我们看看这台漂亮的打印机在工作。考虑一下主.cpp下面的文件


class Vector {
public:
    double* myElements;
    unsigned int length;

public:
    Vector(unsigned int length) : length(length) {
        myElements = new double[length];
        for (unsigned int i = 0; i < length; i++) {
            myElements[i] = i;
        }
    }

    ~Vector() {
        delete[] myElements;
    }
};

int main(int argc, char *argv[])
{
    Vector v(10);
    return 0;
}

如果我们在gdb中打印v,我们得到

pretty printting vector v


注意:如果您感兴趣,我为armadillo库中的vector、matrix和cube类以及std::complex创建了一些漂亮的打印机。这些漂亮的打印机是可用的here。查看代码可能有助于创建其他漂亮的打印机。你知道吗

相关问题 更多 >