GDB pretty printer for 类 来自一个基
GDB pretty printer for classes derived from one base
我想在我的 .gdbinit 中添加一个漂亮的打印机,它将用于从包含 "value" 的 class 基派生的任何类型。这部分有效:
class MyBasePrinter(gdb.printing.PrettyPrinter):
def __init__(self, val):
self.__val = val['value']
def to_string(self):
return self.__val
my_pretty_printer = gdb.printing.RegexpCollectionPrettyPrinter('my_printer')
my_printer.add_printer('Base', '^Base.*$', MyBasePrinter)
不幸的是,我在 gdb 中打印的内容是这样的:
= {<Base class stuff> = <value>}
Base class 是一个 CRTP 模板,因此 "Base class stuff" 变得很长。
或者,我可以为每个派生的 classes 添加一个单独的漂亮打印机,在这种情况下打印效果很好,但是每次有人从 Base 派生新的 class 时,.gdbinit 都需要更改。我想知道是否有更好的解决方案?理想情况下,我希望看到打印出类似
的内容
= <Derived> = <value>
Base 和 Derived 的最小代码示例:
template <typename RawType, typename T, template <typename> typename...Traits>
struct IntegralValue : Traits<T>... {
using raw_type = RawType;
raw_type value;
explicit IntegralValue(raw_type v) : value(v) { }
void operator=(IntegralValue const& rhs) { value = rhs.value; }
};
template <typename T> struct EqualComparable {
bool operator==(T rhs) const {
return static_cast<T const*>(this)->value == rhs.value;
}
bool operator!=(T rhs) const {
return static_cast<T const*>(this)->value != rhs.value;
}
};
template <typename T> struct Incrementable {
T operator++(int) {
auto& self = static_cast<T&>(*this);
T retval = self;
self.value++;
return retval;
}
// other increment-related operators here
// ...
};
struct SequenceNumber : IntegralValue<uint64_t, SequenceNumber, EqualComparable, Incrementable> {
explicit SequenceNumber(raw_type v) : IntegralValue(v) { }
};
struct Id : IntegralValue<uint64_t, Id, EqualComparable> {
explicit Id(raw_type v) : IntegralType(v) { }
};
auto id = Id(1);
auto s = SequenceNumber(2);
// stop gdb around here and print id and s
您的代码有:
my_pretty_printer = gdb.printing.RegexpCollectionPrettyPrinter('my_printer')
虽然 gdb 漂亮打印机通常按类型名称注册——并且有像这样的帮助程序可以使它更简单——但实际上并不需要。相反,你可以有一个接受任何值的识别器,并决定是否为它构建一个漂亮的打印机。
请参阅 gdb.pretty_printers
in the manual 部分。您的识别器可以通过检查值的类型来查看它是否派生自 Base
.
我想在我的 .gdbinit 中添加一个漂亮的打印机,它将用于从包含 "value" 的 class 基派生的任何类型。这部分有效:
class MyBasePrinter(gdb.printing.PrettyPrinter):
def __init__(self, val):
self.__val = val['value']
def to_string(self):
return self.__val
my_pretty_printer = gdb.printing.RegexpCollectionPrettyPrinter('my_printer')
my_printer.add_printer('Base', '^Base.*$', MyBasePrinter)
不幸的是,我在 gdb 中打印的内容是这样的:
= {<Base class stuff> = <value>}
Base class 是一个 CRTP 模板,因此 "Base class stuff" 变得很长。 或者,我可以为每个派生的 classes 添加一个单独的漂亮打印机,在这种情况下打印效果很好,但是每次有人从 Base 派生新的 class 时,.gdbinit 都需要更改。我想知道是否有更好的解决方案?理想情况下,我希望看到打印出类似
的内容 = <Derived> = <value>
Base 和 Derived 的最小代码示例:
template <typename RawType, typename T, template <typename> typename...Traits>
struct IntegralValue : Traits<T>... {
using raw_type = RawType;
raw_type value;
explicit IntegralValue(raw_type v) : value(v) { }
void operator=(IntegralValue const& rhs) { value = rhs.value; }
};
template <typename T> struct EqualComparable {
bool operator==(T rhs) const {
return static_cast<T const*>(this)->value == rhs.value;
}
bool operator!=(T rhs) const {
return static_cast<T const*>(this)->value != rhs.value;
}
};
template <typename T> struct Incrementable {
T operator++(int) {
auto& self = static_cast<T&>(*this);
T retval = self;
self.value++;
return retval;
}
// other increment-related operators here
// ...
};
struct SequenceNumber : IntegralValue<uint64_t, SequenceNumber, EqualComparable, Incrementable> {
explicit SequenceNumber(raw_type v) : IntegralValue(v) { }
};
struct Id : IntegralValue<uint64_t, Id, EqualComparable> {
explicit Id(raw_type v) : IntegralType(v) { }
};
auto id = Id(1);
auto s = SequenceNumber(2);
// stop gdb around here and print id and s
您的代码有:
my_pretty_printer = gdb.printing.RegexpCollectionPrettyPrinter('my_printer')
虽然 gdb 漂亮打印机通常按类型名称注册——并且有像这样的帮助程序可以使它更简单——但实际上并不需要。相反,你可以有一个接受任何值的识别器,并决定是否为它构建一个漂亮的打印机。
请参阅 gdb.pretty_printers
in the manual 部分。您的识别器可以通过检查值的类型来查看它是否派生自 Base
.