Привет,
Я снова с GDB. Теперь пытаюсь написать GDB command корорая мне напечатает вектор как нужно. Но почему-то не могу из gdb.Value (std::vector<Foo>) добраться ни до размера вектора ни до его данных.
Т.е. есть приблизительно такой код:
struct Foo {
int a;
explicit Foo(in a) : a(a) {}
};
int main() {
std::vector<Foo*> v = { new Foo(1), new Foo(2), new Foo(3) };
return 0;
}
Сейчас я печатаю вектор в такой способ:
def FooVect (gdb.Command):
def __init__(self):
super(FooVect, self).__init__('foovect', gdb.COMMAND_OBSCURE, gdb.COMPLETE_SYMBOL)
def invoke(self, arg, from_tty):
size = gdb.parse_and_eval('({0}).size()'.format(arg))
for i in range(0, size):
print '[{0}] {1}'.format(i, gdb.parse_and_eval('({0})[{1}].a'.format(i, arg)))
Потом в gdb:
(gdb) foovect v
[0] 1
[1] 2
[2] 3
Однако parse_and_eval
довольно медленный и когда количество итемов растет, приходится долго ждать. Насколько я понимаю parse_and_eval
«вытягивает» целый символ с вместе потрохами. Т.е. можно было бы обойтись одним вызовом parse_and_eval
.
Но если код invoke
(например) сделать таким:
v = gdb.parse_and_eval(arg)
print v[0]
То ничего не получается:
Traceback (most recent call last):
File "<string>", line 2, in <module>
gdb.error: Cannot subscript requested type.
Error while executing Python code.
Более того: в через v
вообще не видно как достаться до данных вектора:
(gdb) python
>v = gdb.parse_and_eval('v')
>print dir(v)
>end
['__abs__', '__add__', '__and__', '__call__', '__class__', '__delattr__', '__delitem__', '__div__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__int__', '__invert__', '__le__', '__len__', '__long__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__nonzero__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rxor__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'address', 'cast', 'const_value', 'dereference', 'dynamic_cast', 'dynamic_type', 'fetch_lazy', 'is_lazy', 'is_optimized_out', 'lazy_string', 'reference_value', 'referenced_value', 'reinterpret_cast', 'string', 'type']
Есть идеи? Может системные pretty-printers для std::vector мешают?
(gdb) python
>v = gdb.parse_and_eval('combinedPUPaths')
>print v
>end
std::vector of length 3, capacity 4 = {
0x7f3edd4d66f0,
0x7f3edd4d6710,
0x7f3edd4d6720
}
P.S.
$ cat ~/.gdbinit
set print array on
set print pretty on
set print object on
set print static-members off