Cython: Error de segmentación al utilizar elementos de Python en el método struct
Tengo estos archivos para reproducir el problema, mod2.pxd:
cdef public api:
void myapi()
cdef public:
cppclass myclass:
void mymethod()
mod2.pyx
cdef void myapi():
print("Estoy bien (desde myapi)")
cdef cppclass myclass:
void mymethod():
# El uso de cualquier cosa en C está bien
cdef int i = 0
i += 1
# Se bloquea con una variable de Python
# Error de segmentación
j = 0
j += 1
# Se bloquea con una función de Python
# Error de segmentación
print("¡Estoy fallando!")
mod1.pxd
cdef public api:
void myfunc()
mod1.pyx
from mod2 cimport myapi, myclass
cdef public cppclass foo:
void bar():
print("Estoy bien (desde foo.bar)")
cdef void myfunc():
print("Estoy bien")
myapi()
cdef foo f
f.bar()
# Variable de pila: Error de segmentación
print("Llamando a myclass.mymethod...")
cdef myclass t
t.mymethod()
# # Puntero: Error de segmentación
# print("Llamando a myclass.mymethod...")
# cdef myclass* t2 = new myclass()
# t2.mymethod()
cpdef test():
myfunc()
Programa principal de Python app.py
import mod1
mod1.test()
Resultado
Estoy bien
Estoy bien (desde myapi)
Estoy bien (desde foo.bar)
Llamando a myclass.mymethod...
Error de segmentación
Es un error de segmentación que ocurre en una estructura de Cython myclass
al usar cualquier cosa de Python. También ocurre en mod2, pero la función global myapi
está bien. Desde un método de la estructura foo.bar
pero en el mismo archivo también está bien.
Estoy usando Python 3.8.2 y Cython 0.29.26.
mod1 y mod2 se traducen a C++ con el comando cython -3 --cplus
y se compilan con gcc
en archivos .so. Ocurre lo mismo al utilizar la herramienta de compilación de Python.
Como se sugiere en https://stackoverflow.com/a/55669343/5581893, intenté agregar -DCYTHON_PEP489_MULTI_PHASE_INIT=0
a todos los comandos gcc
pero no ayudó.
Esta situación parece extraña, ¿por qué las cosas de Python no son accesibles desde mod2 (falla solo en la estructura)?
davy.ai
El problema parece estar en la interacción entre objetos de Python y estructuras de Cython. En el módulo 2, se define la estructura “myclass” con un método “mymethod()”, el cual produce un fallo cuando se usa con una variable o función de Python. Esto sugiere que hay un problema de gestión de memoria en la interacción entre ambos.
En el módulo 1, la función “myfunc()” llama a “myclass.mymethod()”, lo cual provoca una violación de segmento. Estos problemas persisten incluso al compilar con “cython -3 –cplus” y “gcc”.
Una posible solución sugerida en Stack Overflow, que consiste en agregar “-DCYTHON_PEP489_MULTI_PHASE_INIT=0” a los comandos de “gcc”, no resolvió el problema.
No está claro por qué no se pueden acceder a los objetos de Python desde mod2, pero el problema puede estar relacionado con la gestión de memoria y la interacción entre Python y el código de C/C++ en Cython.