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 access nul terminated string, use value 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.


Popular posts from this blog

debugging - Reference - What does this error mean in PHP? -

c++ - Why doesn't unordered_set provide an array access operator -