python gdb 和 ctypes

标签 python gdb ctypes

我正在尝试实现一个调试助手,它应该对 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.Valuedereferencecast等。

关于python gdb 和 ctypes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5637718/

相关文章:

c++ - 如何在核心转储中检查堆大小和创建的对象

c - gdb:线程调试不可用?

c++ - 使用带有 python 的 DLL(使用 ctypes),不工作

android - Kivy 中的 build.py 脚本编译错误

python - 如何从python中的文本文件中获取子字符串?

python - 检查数字是否在两个数字内的更简洁的方法,如果不在则更改它

gdb - gdb 中有 "until"命令吗?

python - 使用 ctypes 在 Python 中使用 Fortran 可选参数

python : multiprocessing and Array of c_char_p

Python Pandas : Boolean indexing on multiple columns