Как стать автором
Обновить

Комментарии 16

Отличная штука. Но меня больше волнует, что будет с отладкой кода со всякими корутинами… Уже даже реализация в clang есть.

Ничего страшного не будет. Duel.py использует официальный gdb python API, то есть gdb.lookup_symbol() и все такое. Все проверки доступности переменных и правильности адресов — на стороне gdb. Если что, выдаст ошибку, мол invalid address или unknown variable. Так же, как если б этот адрес или переменную использовать в любой другой команде gdb, скажем в print.
Классная штука! Обычно я пишу небольшой тест и работаю с задампленными данными. В интерактиве редко получается, в основном batch-mode. Но галочку поставил, никогда не знаешь где инструмент пригодится :)
Кстати — если исходник скажем фортран, это будет работать?
Должно, конечно (если gdb правильно фортрановские переменные и массивы в питон транслирует). Но синтаксис выражений останется С-шный :)

Подскажите касательно gdb. Как с помощью него можно найти все адреса, содержащие некоторый magic. Удобно для поиска тэгированных объектов в дампах. В windbg это делается, например, так "s -d 0 L?-1 0xdeadbeef".

Никогда не пользовался. Но есть же help:
(gdb) h find
Search memory for a sequence of bytes.
Usage:
find [/size-char] [/max-count] start-address, end-address, expr1 [, expr2 ...]
find [/size-char] [/max-count] start-address, +length, expr1 [, expr2 ...]
size-char is one of b,h,w,g for 8,16,32,64 bit values respectively,
and if not specified the size is taken from the type of the expression
in the current language.
Note that this means for example that in the case of C-like languages
a search for an untyped 0x42 will search for "(int) 0x42"
which is typically four bytes.

The address of the last match is stored as the value of "$_".
Convenience variable "$numfound" is set to the number of matches.

Да, find'ом пробовал, но он спотыкается на первом же inaccessible адресе. Думал, есть какое-то средство из коробки для такого действия. На данный момент я вижу только такой способ: получать список замапленных регионов и искать find'ом в каждом из них.

Выглядит полезным. На lldb втянуть трудно?

Честно говоря, не смотрел. В lldb тоже есть какой-то Python API, но на gdb-шный он, естественно, не похож. Тем не менее, основные вещи там, вроде, похожи — ну, есть symbols, у них есть values, и эти values поддерживают обычные питоновские операторы. То есть, кажется, что нетрудно. только заменить (а лучше абстрагировать и прислать мне pull request) несколько методов из gdb.* — такие как write, lookup_symbol, lookup_global_symbol, gdb.error (это исключение, что gdb бросает), ну, может, еще что-то. Немного.

Очень полезная штука.
Только почему у меня выдает: "'gdb.Value' object cannot be interpreted as an integer" на любой оператор… ?

Совсем на любой?
* пример, пожалуйста
* какая версия duel-а?
* какая версия gdb и питона?

Да нет же) operator (..)
(gdb) dl(1,5)
(1) = 1
(5) = 5
(gdb) dl (1..5)
'gdb.Value' object cannot be interpreted as an integer


GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Python 2.7.6
duel прямо с гитхаба, только что сгрузил

Может быть слишком старый gdb. На 7.10 у меня все работало. Проверьте вот такое:
(gdb) pi import sys
(gdb) pi sys.version
'2.7.12 (default, Dec 19 2016, 22:50:06) \n[GCC 4.9.3]'
(gdb) pi dir(gdb.Value(1))
[ ... '__int__', ... '__long__', ... ]
(gdb) pi range(gdb.Value(1), gdb.Value(5))
[1, 2, 3, 4]
(gdb) 

То есть в методах у gdb.Value должны быть __int__ и __long__. И range от gdb.Value должен работать. Если что-то будет не так, может быть я смогу вставить костыль.
(gdb) pi import sys
(gdb) pi sys.version
'3.4.3 (default, Nov 17 2016, 01:12:14) \n[GCC 4.8.4]'
(gdb) pi dir(gdb.Value(1))
['__abs__', '__add__', '__and__', '__bool__', '__call__', '__class__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__float__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__int__', '__invert__', '__le__', '__len__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__xor__', 'address', 'cast', 'dereference', 'dynamic_cast', 'dynamic_type', 'fetch_lazy', 'is_lazy', 'is_optimized_out', 'lazy_string', 'referenced_value', 'reinterpret_cast', 'string', 'type']
(gdb) pi range(gdb.Value(1), gdb.Value(5))
Python Exception <class 'TypeError'> 'gdb.Value' object cannot be interpreted as an integer:
Error while executing Python code.
(gdb)

Я так понимаю зло в буковках 3.4.3? Можете что-нибудь посоветовать? Я с питоном нмкогда к сожалению дела не имел, а использовать ваш модуль очень хочется, причем на работе, где я над версиями не властен.

Не знаю, то ли gdb-7.7.1, то ли python 3.4.3 — но кто-то из них виноват. Ошибка странная, потому что у gdb.Value есть метод __int__, так что as integer он точно может быть interpreted.

В общем, я нашел такую же точно убунту, эффект повторился. Я пушнул костыль, скачайте свежую версию.
Работает, спасибо. Буду пользоваться и вспоминать добрым словом.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории