Resumen: Estoy tratando de averiguar qué configuraciones en mi compilador cambiarían cómo se configuran los elementos en la memoria

Detalles: Tengo dos versiones del mismo archivo de biblioteca (libgbm.so), una proporcionada como un binario prediseñado y otra compilada en mi propia máquina. Se trabaja correctamente y se arroja una falla de segmentación. Parece que mi compilador está manejando mis estructuras de datos de manera diferente a la versión precompilada.

He proporcionado una versión reducida del código (consulte las estructuras asociadas en la parte inferior). Básicamente, carga una biblioteca compartida y llama a la función create_device(). Eso devuelve una estructura de datos (gbm_device) con un montón de punteros de función.

gbm_create_device(int fd)
{
   struct gbm_device *gbm = NULL;
   void *module;
   const struct gbm_backend *backend = NULL

   module = dlopen("/usr/lib/gbm/gbm_pvr.so", RTLD_NOW | RTLD_GLOBAL);
   backend = dlsym(module, "gbm_backend");
   gbm = backend->create_device(fd);

   gbm->surface_create(gbm, width, height, format, flags);
}

Aquí es donde el código se ejecuta de manera diferente. Cuando se usa la biblioteca precompilada, GDB muestra el siguiente paso después de gbm->surface_create como

0xb6beb5d0 in ?? () from /usr/lib/gbm/gbm_pvr.so

Cuando utilizo mi versión compilada localmente, GDB muestra el siguiente paso como

0xb6c414a4 in ?? () from /usr/lib/gbm/gbm_pvr.so

No tengo los símbolos de depuración para gbm_pvr.so (biblioteca propietaria), pero el código obviamente está entrando en dos funciones diferentes (al menos los últimos 3 dígitos de la dirección de memoria deberían ser los mismos).

Lo único en lo que puedo pensar es que hay una configuración de compilador / enlazador que me perdí y que cambia la forma en que la estructura gbm_device se presenta en la memoria, estropeando así todos los punteros que obtiene.


Aquí están las estructuras asociadas

struct gbm_device {
   /* Hack to make a gbm_device detectable by its first element. */
   struct gbm_device *(*dummy)(int);

   int fd;
   const char *name;
   unsigned int refcount;
   struct stat stat;

   void (*destroy)(struct gbm_device *gbm);
   int (*is_format_supported)(struct gbm_device *gbm,
                              uint32_t format,
                              uint32_t usage);

   struct gbm_bo *(*bo_create)(struct gbm_device *gbm,
                               uint32_t width, uint32_t height,
                               uint32_t format,
                               uint32_t usage);
   struct gbm_bo *(*bo_import)(struct gbm_device *gbm, uint32_t type,
                               void *buffer, uint32_t usage);
   int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data);
   int (*bo_get_fd)(struct gbm_bo *bo);
   void (*bo_destroy)(struct gbm_bo *bo);

   struct gbm_surface *(*surface_create)(struct gbm_device *gbm,
                                         uint32_t width, uint32_t height,
                                         uint32_t format, uint32_t flags);
   struct gbm_bo *(*surface_lock_front_buffer)(struct gbm_surface *surface);
   void (*surface_release_buffer)(struct gbm_surface *surface,
                                  struct gbm_bo *bo);
   int (*surface_has_free_buffers)(struct gbm_surface *surface);
   void (*surface_destroy)(struct gbm_surface *surface);
};

Y

struct gbm_backend {
   const char *backend_name;
   struct gbm_device *(*create_device)(int fd);
};
0
user8908459 11 nov. 2017 a las 22:59

2 respuestas

La mejor respuesta

Resolví el problema.

Mi entorno de compilación estaba agregando automáticamente las siguientes banderas del compilador. Eliminar estos solucionó el problema.

-D_LARGEFILE_SOURCE
-D_LARGEFILE64_SOURCE
-D_FILE_OFFSET_BITS=64 
0
user8908459 12 nov. 2017 a las 19:11

No creo que la diferencia en las compensaciones de código dentro de la página sea evidencia de una diferencia en el diseño de la estructura. El diseño del código puede cambiar fácilmente debido a las diferencias en las versiones del compilador, ensamblador y enlazador y la configuración de optimización.

Es posible que el objeto compartido simplemente use una definición diferente de la estructura. Con las definiciones que publicó, tendría que usar algo como #pragma pack para crear un diseño diferente, y parece poco probable que esta sea la causa.

EDITAR Me perdí el miembro struct stat. Esto es realmente un no-no porque cambia de tamaño dependiendo del valor de _FILE_OFFSET_BITS (como ino_t y off_t). El código portátil no debe usar estos tipos (y time_t) en archivos de encabezado públicos.

2
Florian Weimer 16 nov. 2017 a las 14:37