Hi,

I was testing my cython codebase on top of pypy/cpyext, and I found a
memory corruption.  After investigating it with the pypy guys (thanks
arigato!), we identified it as a cython bug:

 cdef void test(char *string):
     print(string)

 def run(array):
     test(array[0])


This code works fine under cpython, but looking at the generated code
for the last line, the call to test is done with a pointer (__pyx_t_2)
to some potentially deallocated string (__pyx_t_1), which isn’t freed
just yet on cpython but is on pypy:

 __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_array, 0, …);
 __Pyx_GOTREF(__pyx_t_1);
 __pyx_t_2 = __Pyx_PyObject_AsString(__pyx_t_1);
 __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 __pyx_f_1a_test(__pyx_t_2);


The obvious solution is to swap the last two lines, it then works fine
on pypy (although not necessarily if the test function stores the
pointer somewhere, but it’s not cython’s fault then).

This issue can also happen with an explicit cast:

 pointer = <char *>array[0]
 test(pointer)


I’m not sure if it should be addressed the same way, because that would
mean keeping a reference to array[0] for all the lifetime of the
current scope, but it could still prevent obscure bugs like the memory
corruption I had.

-- 
Emmanuel Gil Peyrot

Attachment: pgpq8i4NyR8z2.pgp
Description: PGP signature

_______________________________________________
cython-devel mailing list
[email protected]
https://mail.python.org/mailman/listinfo/cython-devel

Reply via email to