我正在尝试实现一个调试助手,它应该对 xml 节点进行字符串化。我正在使用 gdb 7.2s python 接口(interface)来执行此操作。这个想法是获取节点地址,然后使用 ctypes 将其传递给 xml 库。
我已经设法获得了 xml 节点地址(一个 gdb.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 # gdb.Value containing the addr of xmlNodePtr cur
pDoc # gdb.Value containing 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)
这通常会让我在 xmlNodeDump 处发生 gdb 崩溃。关于我做错了什么的任何提示?
最佳答案
想想你在做什么。它可能不起作用!
你得到一个 gdb.Value,表示 xmlNodePtr
inferior(被调试)进程的地址。
然后将该地址传递给 libxml2.so.2
,加载到 GDB 自身。
但是inferior 中的地址在GDB 中很可能是不可访问的。如果碰巧它是可访问的,它几乎肯定不指向 xmlNode
。如果奇迹般地它确实指向 xmlNode
,它仍然不是您想要的节点(不是劣质进程中的节点)。
有两种方法可以解决这个问题。
- 如果你有一个实时的劣质进程(即你没有进行事后调试),你可以简单地从 gdb 调用
xmlNodeDump
:call xmlNodeDump(a_pointer)
- 如果你正在进行事后调试,或者只是不想调用劣质进程(这样做会“打扰”劣质进程),你必须完全重新实现
xmlNodeDump
Python,使用gdb.Value
,dereference
,cast
等。
关于python gdb 和 ctypes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5637718/