2012-07-06 14 views
8

Estoy tratando de portar un código Python ctypes de un programa específico de Windows para vincularlo con un puerto Linux de mi biblioteca. El ejemplo de código de Python más corto que describe mi problema se muestra a continuación. Cuando intento ejecutarlo, recibo un error de segmentación en examine_arguments() en Python. Puse una declaración printf en mi biblioteca en la llamada a la función de bloqueo, pero nunca se ejecuta, lo que me lleva a pensar que el problema está en el código de los tipos.Debugging Pitthon ctypes segmentation fault

import ctypes 

avidll = ctypes.CDLL("libavxsynth.so") 


class AVS_Value(ctypes.Structure, object): 
    def __init__(self, val=None): 
     self.type=ctypes.c_short(105) # 'i' 
     self.array_size = 5 
     self.d.i = 99 


class U(ctypes.Union): 
    _fields_ = [("c", ctypes.c_void_p), 
       ("b", ctypes.c_long), 
       ("i", ctypes.c_int), 
       ("f", ctypes.c_float), 
       ("s", ctypes.c_char_p), 
       ("a", ctypes.POINTER(AVS_Value))] 


AVS_Value._fields_ = [("type", ctypes.c_short), 
         ("array_size", ctypes.c_short), 
         ("d", U)] 


avs_create_script_environment = avidll.avs_create_script_environment 
avs_create_script_environment.restype = ctypes.c_void_p 
avs_create_script_environment.argtypes = [ctypes.c_int] 

avs_set_var = avidll.avs_set_var 
avs_set_var.restype = ctypes.c_int 
avs_set_var.argtypes = [ctypes.c_void_p, ctypes.c_char_p, AVS_Value] 


env = avs_create_script_environment(2) 
val = AVS_Value() 
res = avs_set_var(env, b'test', val) 

Mi biblioteca tiene lo siguiente en sus cabeceras, y un programa normal-C haciendo lo que describo más arriba (llamando create_script_environment seguido por set_var) funciona muy bien. En cuanto a la información de registro que mi biblioteca está poniendo en la consola, el bloqueo ocurre cuando intento ingresar al avs_set_var.

typedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment; 
typedef struct AVS_Value AVS_Value; 
struct AVS_Value { 
    short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong 
       // for some function e'rror 
    short array_size; 
    union { 
    void * clip; // do not use directly, use avs_take_clip 
    char boolean; 
    int integer; 
    float floating_pt; 
    const char * string; 
    const AVS_Value * array; 
    } d; 
}; 
AVS_ScriptEnvironment * avs_create_script_environment(int version); 
int avs_set_var(AVS_ScriptEnvironment *, const char* name, AVS_Value val); 

me trataron backtracing la llamada del BGF, pero no entienden cómo interpretar los resultados, ni realmente mucho sobre el uso de BGF.

#0 0x00007ffff61d6490 in examine_argument() from /usr/lib/python2.7/lib-dynload/_ctypes.so 
#1 0x00007ffff61d65ba in ffi_prep_cif_machdep() from /usr/lib/python2.7/lib-dynload/_ctypes.so 
#2 0x00007ffff61d3447 in ffi_prep_cif() from /usr/lib/python2.7/lib-dynload/_ctypes.so 
#3 0x00007ffff61c7275 in _ctypes_callproc() from /usr/lib/python2.7/lib-dynload/_ctypes.so 
#4 0x00007ffff61c7aa2 in PyCFuncPtr_call.2798() from /usr/lib/python2.7/lib-dynload/_ctypes.so 
#5 0x00000000004c7c76 in PyObject_Call() 
#6 0x000000000042aa4a in PyEval_EvalFrameEx() 
#7 0x00000000004317f2 in PyEval_EvalCodeEx() 
#8 0x000000000054b171 in PyRun_FileExFlags() 
#9 0x000000000054b7d8 in PyRun_SimpleFileExFlags() 
#10 0x000000000054c5d6 in Py_Main() 
#11 0x00007ffff68e576d in __libc_start_main() from /lib/x86_64-linux-gnu/libc.so.6 
#12 0x000000000041b931 in _start() 

No sé cómo abordar este problema. He visto los detalles de los tipos de llamadas, pero no veo nada obviamente incorrecto allí. ¿Estoy cayendo en usos de tipos específicos de la plataforma?

Editar Parece que hay un problema con las arquitecturas de 32 bits frente a las de 64 bits en el módulo ctypes. Cuando probé esto de nuevo con una compilación de 32 bits de mi biblioteca y Python de 32 bits, se ejecutó con éxito. En 64 bits, segfaults en el mismo lugar.

+0

He copiado el código, reorganizado los bits claramente mal pegado, hice algunas implementaciones de relleno de las dos funciones, compilado para x86_64, y lo ejecutó en un Python 2.7 de 64 bits (Ubuntu Natty, gcc 4.5.2, Python 2.7.1, eglibc 2.13), y todo funcionó como se esperaba. Parece prematuro culpar al problema de los ctypes aquí; tal vez puede proporcionar un ejemplo más completo de ruptura? –

+0

Limpié el ejemplo de código. Parece que segfault está relacionado con que la unión sea parte de la clase AVS_Value. Cuando lo reemplazo con algo como ctypes.c_int o ctypes.c_void_p, el programa ya no segmenta. Estoy empezando a pensar que el problema está en Python instalado en Ubuntu, estoy usando Ubuntu 12.04, GCC 4.6.3, Python 2.7 .. – user1505563

Respuesta

0

Trate de usar c_void_p para la opaca AVS_ScriptEnvironment*:

avs_create_script_environment.restype = c_void_p 

y:

avs_set_var.argtypes=[c_void_p,ctypes.c_char_p,AVS_Value] 
+0

Establecer explícitamente el tipo de devolución en c_void_p no ayuda. No veo por qué lo haría, ya que Python falla antes de ingresar a la siguiente función, por lo que no se hace nada con ese puntero. – user1505563