Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python gdb and ctypes

Tags:

python

gdb

ctypes

I'm trying to implement a debugging helper, which should stringify an xml node. I'm using gdb 7.2s python interface to do this. The idea is to get the nodes address, then pass it to the xml library using ctypes.

I've managed to get the xml nodes address (a gdb.Value) and I can call functions in the xml library. But somehow, the ends don't meet.

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

And the python part calling this function:

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

This usually gives me a gdb crash at xmlNodeDump. Any hints of what I'm doing wrong?

like image 915
christoph Avatar asked Sep 09 '26 07:09

christoph


1 Answers

Think about what you are doing. It can't possibly work!

You get a gdb.Value, representing the address of xmlNodePtr in the inferior (being debugged) process.

You then pass that address into libxml2.so.2, loaded into GDB itself.

But the address in the inferior is very likely inaccessible within GDB. If by chance it is accessible, it almost certainly does not point to an xmlNode. And if by miracle it does point to xmlNode, it would still not be the node you want (not the one in the inferior process).

There are two ways to fix this.

  • If you have a live inferior process (i.e. you are not doing post-mortem debugging), you can simply call xmlNodeDump from gdb: call xmlNodeDump(a_pointer)
  • If you are doing post-mortem debugging, or just don't want to call into the inferior process (doing so "disturbs" the inferior), you have to re-implement xmlNodeDump entirely in Python, using gdb.Value, dereference, cast, etc. etc.
like image 177
Employed Russian Avatar answered Sep 11 '26 20:09

Employed Russian