Reputation: 4088
I am looking into some code I have not written with pdb.
(Pdb) self.function
<CFunctionType object at 0x000000DC768E0E18>
(Pdb) type(self.function)
<class 'ctypes.CFUNCTYPE.<locals>.CFunctionType'>
(Pdb) dir(self.function)
['__bool__', '__call__', '__class__', '__ctypes_from_outparam__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_argtypes_', '_b_base_', '_b_needsfree_', '_flags_', '_objects', '_restype_', 'argtypes', 'errcheck', 'restype']
(Pdb) self.function._flags_
1
(Pdb) self.function._objects
{'0': <CDLL 'C:\path', handle 7ffe26465400 at 0xdc74ad2908>}
Is it possible for me to find out where self.function was defined, or what the name of the function is? self.function._objects points towards a DLL, but it's not clear to me how or if I can find the function's name so I can look it up in the source code.
Further, is it possible to step into the function when it is called? It is called in the code in the following way:
self.function(*self.args)
Upvotes: 3
Views: 877
Reputation: 366013
Is it possible for me to find out where self.function was defined,
No, because it was defined in some source code written in C (or another language) that you don't even have (or maybe you do, but Python has no idea where it is); all you have is the DLL/so/dylib that resulted from compiling it.
… or what the name of the function is?
Yes. You can usually get the name of a ctypes C function the same way as many other objects in Python: via the __name__
special attribute:
>>> import ctypes
>>> libm = ctypes.CDLL('libm.dylib')
>>> fabs = libm.fabs
>>> fabs
<_FuncPtr object at 0x1067ac750>
>>> fabs.__name__
'fabs'
self.function._objects points towards a DLL, but it's not clear to me how or if I can find the function's name so I can look it up in the source code.
You can't get the function name from there. But you can get the library name from there via the _name
attribute:
>>> fabs._objects['0']._name
'libm.dylib'
(Despite the underscore, this is a public attribute, as the docs explain.)
This will usually be the name passed to the CDLL
constructor or cdll.LoadLibrary
call. On Windows, for libraries loaded with the cdll.spam
magic, I think you actually get the resolved pathname, like 'D:\path\to\spam.dll'
, not just 'spam'
or 'spam.dll'
, but I'm not positive.
Further, is it possible to step into the function when it is called?
No, because the function is compiled machine code; it doesn't have any Python bytecode for you to step into.
You could, of course, attach a debugger like Visual Studio, lldb, or gdb and step into the machine code that way.
Upvotes: 5