2015-11-20 3 views
4

Я начал экспериментировать с построением gdb довольно принтеров для некоторых из моих структур данных на C++, но documentation довольно тонкий.Отладка gdb pretty printers

В результате мне нужно угадать, как это делать, и часто мои симпатичные принтеры просто сбой с незаменимым исключением python без указания того, где находится настоящая проблема.

Есть ли хороший способ отладки красивого принтера? Я имел успех в других программах питона, вставив явный вызов pydb в коде:

import pydb 
pydb.debugger() 

, но это не похоже на работу при запуске питона в GDB - это просто проходит мимо debugger вызова и не останавливается, не говорит и не делает ничего.

+1

Убедитесь, что вы установили python print-stack full. Это приведет к полному отслеживанию стека из исключений. Я никогда не пробовал отладчик python для моих симпатичных принтеров; Я в основном закончил отладку отпечатков. –

ответ

1

Вы можете запустить pdb (один из отладчиков python) в пределах gdb. Вот выдержка из Gdb сессии с простым примером:

(gdb) print (ObjectSignature *) 0x7f71e4018000 
$1 = (ObjectSignature *) 0x7f71e4018000 
(gdb) python import pdb 
(gdb) python pdb.run('gdb.execute("print $1[0]")') 
> <string>(1)<module>() 
(Pdb) from svtprinters.printers import ObjectSignaturePrinter 
(Pdb) b ObjectSignaturePrinter.to_string 
Breakpoint 1 at /svtfs/svtprinters/printers.py:195 
(Pdb) c 
$2 = > /svtfs/svtprinters/printers.py(196)to_string() 
-> sizetypestr = 'invalid' 
(Pdb) n 
> /svtfs/svtprinters/printers.py(197)to_string() 
-> sizetypeidx = int(self.val['mSizeType']) 
(Pdb) self.val['mSizeType'] 
<gdb.Value object at 0x7effc90ff430> 
(Pdb) int(self.val['mSizeType']) 
3 
(Pdb) n 
> /svtfs/svtprinters/printers.py(199)to_string() 
-> if sizetypeidx < len(self.sizetypes): 
(Pdb) self.sizetypes 
['unknown', 'meta_1K', 'data_4K', 'data_8K', 'data_16K', 'data_32K', 'data_64K'] 
(Pdb) n 
> /svtfs/svtprinters/printers.py(200)to_string() 
-> sizetypestr = self.sizetypes[sizetypeidx] 
(Pdb) 
> /svtfs/svtprinters/printers.py(202)to_string() 
-> return (20*"%02x"+" %s") % tuple([self.val['mValue'][i] for i in range(20)]+[sizetypestr]) 
(Pdb) sizetypestr 
'data_8K' 
(Pdb) c 
98d6687a2ea63a134901f0df140b13112e64bfb7 data_8K 
(gdb) 

В этом примере ObjectSignaturePrinter является классом, который связан через gdb.pretty_printers с ObjectSignature типом в $1. Выход второй команды print разделен; $2 = печатается до достижения предельной точки прерывания принтера, а остальная часть вывода появляется после команды continue pdb.

Вероятно, варианты этого подхода будут работать с другими отладчиками python.

+0

Когда я пытаюсь это сделать, я могу получить сообщение '(Pdb)', но когда я пытаюсь установить точку останова с помощью 'b MyObjectPrinter.to_string', он просто дает мне сообщение« Конец файла ». продолжайте давать мне тот же gdb.error, не имея возможности выяснить, что не так. Попытка сделать шаг просто зарывает меня в код python gdb –

+0

Я отредактировал свой ответ, чтобы использовать оператор import и более простую команду точки останова. Если я опускаю этот оператор импорта и использую более простую команду breakpoint, я получаю этот вывод: '*** Указанный объект ObjectSignaturePrinter.to_string 'не является функцией или не был найден вдоль sys.path.'. У меня нет объяснения, почему ваша команда breakpoint сообщает об ошибке, о которой он сообщает, но может быть информативным экспериментировать с этим. Если вы наберете только имя функции (опустите символ 'b'), это должно сказать вам, распознает ли это имя' pdb'. –

+0

Я нашел явный источник сообщения «Конец файла» в 'Pdb.checkline' ('/usr/lib/python2.7/pdb.py' в моей системе, для двоичного файла gdb, который я использую для этого). Я не уверен, почему он найдет строку, которую он не считает исполняемым, если вы укажете только имя функции. Даже если я заменил свой метод 'to_string' на просто инструкцию' pass' или просто строку и ничего больше, точка останова будет работать для меня. Как и прежде, может быть полезно узнать, как 'pdb' интерпретирует это имя функции. Для меня он отображается как unbound метод после импорта (я получаю 'NameError', если я пытаюсь перед импортом). –