python gdb и ctypes

#python #&db #ctypes

#python #&db #ctypes

Вопрос:

Я пытаюсь реализовать помощник по отладке, который должен упорядочивать xml-узел. Для этого я использую python-интерфейс &db 7.2. Идея состоит в том, чтобы получить адрес узлов, а затем передать его в библиотеку xml с помощью ctypes.

Мне удалось получить адрес узлов xml (&db.Value), и я могу вызывать функции в библиотеке xml. Но почему-то концы с концами не сходятся.

 // prototype of functions to call
int xmlNodeDump (xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level, int format);
xmlBufferPtr xmlBufferCreate(void);
  

И часть python, вызывающая эту функцию:

 # this is xmlBuffer
class lxmlBufferStruct(Structure):
    _fields_ = [('content', POINTER(c_ubyte)),
        ('use', c_uint), ('size', c_uint),
        ('alloc', c_int), ('contentIO', POINTER(c_ubyte))]
pNode # &db.Value containin& the addr of xmlNodePtr cur
pDoc # &db.Value  containin& addr of xmlDocPtr doc

libxml2 = CDLL('libxml2.so.2')
xmlBufferCreate = libxml2.xmlBufferCreate
xmlBufferCreate.restype = POINTER(lxmlBufferStruct)
xmlBuf = xmlBufferCreate()
libxml2.xmlNodeDump(buf, c_void_p(int(str(pDoc), 16)), 
    c_void_p(int(str(pNode), 16)), 0, 0)
  

Обычно это приводит к сбою &db в xmlNodeDump. Есть какие-нибудь намеки на то, что я делаю неправильно?

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

1. Мне было бы любопытно, являются ли эти адреса все еще действительными — например, определите структуры xmlDoc и XmlNode и попробуйте преобразовать пустые ptr-файлы в указатели этих типов и получить доступ к полям.

2. Следует рассмотреть еще один аспект — я не уверен, безопасно ли предполагать, что поле alloc имеет размер int, поскольку это перечисление. Это может привести к нарушению выравнивания поля contentIO.

Ответ №1:

Подумайте о том, что вы делаете. Это возможно не сработает!

Вы получаете &db.Value, представляющий адрес xmlNodePtr в низшем (отлаживаемом) процессе.

Затем вы передаете этот адрес в libxml2.so.2 , загруженный в саму GDB.

Но адрес в нижней части, скорее всего, недоступен в GDB. Если случайно он доступен, он почти наверняка не указывает на xmlNode . И если каким-то чудом это действительно укажет на xmlNode , это все равно будет не тот узел, который вам нужен (не тот, который находится в низшем процессе).

Есть два способа исправить это.

  • Если у вас запущенный процесс низкого уровня (т. Е. вы не выполняете посмертную отладку), вы можете просто вызвать xmlNodeDump из &db: call xmlNodeDump(a_pointer)
  • Если вы выполняете посмертную отладку или просто не хотите вызывать подчиненный процесс (это «мешает» подчиненному процессу), вам придется xmlNodeDump полностью повторно реализовать его на Python, используя &db.Value , dereference cast и т.д. И т.п.

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

1. По какой-то причине я предположил, что &db загружается в то же адресное пространство, что и нижестоящий. Если это не так, то понятно, почему поведение моего скрипта довольно случайное.

2. Я задавался вопросом, почему раньше работали помощники по отладке c : они были внедрены в процесс debu&&ee.