python c segmentation-fault fgetc

python - fgetc causa una segfault después de ejecutar la segunda vez



segmentation-fault (0)

Tengo una aplicación que intenta leer un archivo clave específico y esto puede suceder varias veces durante la vida útil del programa. Aquí está la función para leer el archivo:

__status _read_key_file(const char * file, char ** buffer) { FILE * pFile = NULL; long fsize = 0; pFile = fopen(file, "rb"); if (pFile == NULL) { _set_error("Could not open file: ", 1); return _ERROR; } // Get the filesize while(fgetc(pFile) != EOF) { ++fsize; } *buffer = (char *) malloc(sizeof(char) * (fsize + 1)); // Read the file and write it to the buffer rewind(pFile); size_t result = fread(*buffer, sizeof(char), fsize, pFile); if (result != fsize) { _set_error("Reading error", 0); fclose(pFile); return _ERROR; } fclose(pFile); pFile = NULL; return _OK; }

Ahora el problema es que para un solo abrir / leer / cerrar funciona bien, excepto cuando ejecuto la función la segunda vez - siempre segfault en esta línea: while(fgetc(pFile) != EOF)

Rastreando con gdb, muestra que el segfault ocurre más profundamente dentro de la función fgetc. Estoy un poco perdido, pero obviamente estoy haciendo algo mal, ya que si trato de decir el tamaño con fseek / ftell, siempre obtengo un 0.

Algún contexto:

  • Idioma: C
  • Sistema: Linux (Ubuntu 16 64bit)
  • Por favor, ignore las funciones y los nombres con guiones bajos ya que están definidos en otro lugar en el código.
  • El programa está diseñado para ejecutarse como una biblioteca dinámica para cargar en Python a través de ctypes

EDITAR Correcto, parece que hay más de lo que parece. Jean-François Fabre generó una idea que probé y funcionó, sin embargo, todavía estoy confundido por qué.

Un poco de contexto adicional:

Supongamos que hay una función en C que se parece a esto:

_status init(_conn_params cp) { _status status = _NONE; if (!cp.pkey_data) { _set_error("No data, open the file", 0); if(!cp.pkey_file) { _set_error("No public key set", 0); return _ERROR; } status = _read_key_file(cp.pkey_file, &cp.pkey_data); if (status != _OK) return status; } /* SOME ADDITIONAL WORK AND CHECKING DONE HERE */ return status; }

Ahora en Python (usando 3.5 para probar), generamos esos conn_params y luego llamamos a la función init:

from ctypes import * libCtest = CDLL(''./lib/lib.so'') class _conn_params(Structure): _fields_ = [ # Some params (''pkey_file'', c_char_p), (''pkey_data'', c_char_p), # Some additonal params ] #################### PART START ################# cp = _conn_params() cp.pkey_file = "public_key.pem".encode(''utf-8'') status = libCtest.init(cp) status = libCtest.init(cp) # Will cause a segfault ##################### PART END ################### # However if we do #################### PART START ################# cp = _conn_params() cp.pkey_file = "public_key.pem".encode(''utf-8'') status = libCtest.init(cp) # And then cp = _conn_params() cp.pkey_file = "public_key.pem".encode(''utf-8'') status = libCtest.init(cp) ##################### PART END ###################

La segunda PARTE INICIO / PARTE FIN no causará la segfault en este contexto.

¿Alguien sabría una razón de por qué?