How can I troubleshoot a segmentation fault when working with Python Ctypes and C++? -
let's have following 2 function signatures in c++:
byte* init( byte* options, byte* buffer )
and:
int next( byte* interface, byte* buffer )
the idea first initialize interface
class in c++, subsequently call next
function python, reference class.
the first function returns byte
pointer interface via:
interface* interface; // initialize stuff return((byte*) interface);
i call in python this:
class foo: def init(self, data): # left out: setting options_ptr buf = (c_ubyte * len(data.bytes)).from_buffer_copy(data.bytes) init_fun = getattr(self.dll, '?init@@yapaepae0hh@z') init_fun.restype = pointer(c_ubyte) self.interface_ptr = init_fun(options_ptr, buf) # works fine! def next(self, data): # create buf other data buf = (c_ubyte * len(data.bytes)).from_buffer_copy(data.bytes) next_fun = getattr(self.dll, '?next@@yahpae0hn@z') ret = next_fun(self.interface_ptr, buf) # randomly segmentation faults here
i call outside with, e.g.:
foo = foo() foo.init(some_data) foo.next(some_other_data) # ... foo.next(some_additional_data)
now, when run it, segmentation faults:
[1] 24712 segmentation fault python -u test.py
sometimes happens after first call .next()
, happens after eleventh call .next()
—totally @ random.
there c++ test code api works this:
byte buffer[500000]; utin bufsize=0; byte* interface; # not shown here: fill buffer interface = init(buffer); while(true) { # not shown here: fill buffer other data int ret = next(interface, buffer); }
now, cannot show exact code, since it's bigger , proprietary, question is: how can troubleshoot such segmentation fault? can break when exception thrown (when debugging vs2012), breaks here:
clearly, that's not useful because nothing done buffer @ indicated line. , variable values cryptic too:
in case data
bitstring object. problem if c++ code memory operations on buffer passed? or data garbage-collected python when it's still needed?
more generally, how can ensure not getting segmentation faults when working ctypes? know underlying dll api works fine , doesn't crash.
update: when make buf
instance variable, e.g. self._buf
, segmentation fault, breaks @ different location during debugging:
there few misunderstandings had, of led problems:
when create ctypes object in python , pass c function, , python object no longer needed, (probably) garbage-collected , no longer in memory stack c expects be.
therefore, make buffer instance variable, e.g.
self._buf
.the c functions expect data mutable. if c functions not copy data somewhere else work on buffer directly, needs mutable. ctypes documentation specifies this:
assigning new value instances of pointer types c_char_p, c_wchar_p, , c_void_p changes memory location point to, not contents of memory block (of course not, because python strings immutable).
you should careful, however, not pass them functions expecting pointers mutable memory. if need mutable memory blocks, ctypes has
create_string_buffer()
function creates these in various ways. current memory block contents can accessed (or changed)raw
property; if want accessnul
terminated string, usevalue
property:so, did this:
self._buf = create_string_buffer(500000) self._buf.value = startdata.bytes
- the buffer should used in python normal array shown in example code, it's filled , data inside manipulated. so,
.next()
method, did this:
self._buf.value = nextdata.bytes
now program runs expected.