#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.