要点: 我想弄清楚我的编译器中的哪些设置会改变stucts在内存中的设置方式
详细信息: 我有两个版本的相同库文件(libgbm.so),一个作为预先构建的二进制文件提供,一个在我自己的机器上编译。一个正常工作,一个抛出分段错误。看来我的编译器处理的数据结构与预编译版本不同。
我提供了一个精简版的代码(请参阅底部的相关结构)。基本上,它加载一个共享库并调用create_device()
函数。它返回一个带有一堆函数指针的数据结构(gbm_device
)。
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);
}
这是代码以不同方式运行的地方。使用预编译库时,GDB会在gbm->surface_create
之后显示下一步
0xb6beb5d0 in ?? () from /usr/lib/gbm/gbm_pvr.so
使用我的本地编译版本时,GDB将下一步显示为
0xb6c414a4 in ?? () from /usr/lib/gbm/gbm_pvr.so
我没有gbm_pvr.so(专有库)的调试符号,但代码显然是踩到两个不同的函数(至少内存地址的最后3位应该是相同的)。
我能想到的唯一一件事就是我错过了一些编译器/链接器设置,它改变了gbm_device
结构在内存中的布局方式,从而弄乱了所有指针。< / p>
以下是关联结构
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);
};
并且
struct gbm_backend {
const char *backend_name;
struct gbm_device *(*create_device)(int fd);
};
答案 0 :(得分:2)
我不认为页面中代码偏移的差异是结构布局差异的证据。由于编译器,汇编器和链接器版本以及优化设置的不同,代码布局很容易改变。
共享对象可能只使用结构的不同定义。根据您发布的定义,您必须使用类似#pragma pack
的内容来创建不同的布局,这似乎不太可能是原因。
编辑我错过了struct stat
会员。这实际上是禁忌,因为它会根据_FILE_OFFSET_BITS
的值(例如ino_t
和off_t
)更改大小。可移植代码不应在公共头文件中使用这些类型(和time_t
)。
答案 1 :(得分:0)
我弄明白了这个问题。
我的构建环境自动添加以下编译器标志。删除这些修复了问题。
-D_LARGEFILE_SOURCE
-D_LARGEFILE64_SOURCE
-D_FILE_OFFSET_BITS=64