Python的GDB和ctypes
我正在尝试实现一个调试助手,目的是将一个 XML 节点转换成字符串。我使用的是 gdb 7.2 的 Python 接口来完成这个任务。我的想法是先获取节点的地址,然后通过 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 时崩溃。有没有什么提示可以告诉我哪里出错了?
1 个回答
3
想想你正在做的事情。这根本不可能成功!
你得到了一个 gdb.Value,它代表了正在调试的程序中 xmlNodePtr
的地址。
然后你把这个地址传给了 GDB 自身加载的 libxml2.so.2
。
但是,在调试的程序中,这个地址在 GDB 中很可能是无法访问的。如果碰巧可以访问,它几乎肯定不是指向一个 xmlNode
。如果万一它指向了 xmlNode
,那也不一定是你想要的那个(不是在调试程序中的那个)。
有两种方法可以解决这个问题。
- 如果你有一个正在运行的调试程序(也就是说,你不是在进行死后调试),你可以直接在 gdb 中调用
xmlNodeDump
:call xmlNodeDump(a_pointer)
- 如果你是在进行死后调试,或者不想调用调试程序(这样做会“打扰”调试程序),你就需要完全用 Python 重新实现
xmlNodeDump
,使用gdb.Value
、dereference
、cast
等等。