2011-04-12 53 views
3

我试图实现一个调试助手,它应该串联一个XML节点。我使用gdb 7.2s python界面来做到这一点。这个想法是获取节点地址,然后使用ctypes将它传递给xml库。python gdb和ctypes

我已经设法得到xml节点地址(一个gdb.Value),我可以在xml库中调用函数。但不知何故,目的不符合。

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

而蟒蛇部分调用这个函数:

# 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崩溃。我做错了什么暗示?

+0

我会很好奇这些地址仍然有效 - 如定义xmlDoc和xmlNod e结构,并尝试将void ptrs转换为这些类型的指针并访问这些字段。 – 2011-04-12 18:14:36

+0

另一个需要考虑的角度 - 我不确定假设alloc字段是int的大小是否安全,因为它是一个枚举。这可能会严重破坏contentIO字段的对齐。 – 2011-04-12 18:19:09

回答

3

想想你在做什么。它不能可能工作!

您将得到一个gdb.Value,代表地址xmlNodePtr在劣等(正在调试)过程中。

然后,您将该地址传递到libxml2.so.2,加载到GDB 本身

但是在劣势地址很可能在GDB内不可访问。如果偶然,它是可访问的,它几乎肯定是而不是指向xmlNode。如果奇迹它指向xmlNode,它仍然不是你想要的节点(不是下级进程中的节点)。

有两种方法可以解决这个问题。

  • 如果你有一个活下突(即你没有做验尸调试),你可以简单地调用xmlNodeDump从GDB:call xmlNodeDump(a_pointer)
  • 如果你正在做的验尸调试,或只是不”不想打电话到下突(这样做“干扰”下),你必须在Python完全重新实现xmlNodeDump,使用gdb.Valuedereferencecast,等等,等等
+1

出于某种原因,我认为gdb加载到与劣等相同的地址空间。如果这不是真的,那很明显为什么我的脚本的行为是相当随机的。 – christoph 2011-04-13 07:28:14

+0

我想知道为什么调试C++ helpers过去曾经工作过:它们被注入到调试进程中。 – christoph 2011-04-13 07:46:31