摘要:,我正在试图找出编译器中的哪些设置会改变内存中结构设置的方式
详细信息:I有两个版本的同一个库文件(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结构在内存中的布局方式,从而扰乱了它获得的所有指针。
下面是关联结构
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);
};发布于 2017-11-12 19:11:17
我解决了问题。
我的构建环境自动添加了以下编译器标志。移除这些问题解决了问题。
-D_LARGEFILE_SOURCE
-D_LARGEFILE64_SOURCE
-D_FILE_OFFSET_BITS=64 发布于 2017-11-11 21:01:12
我不认为页面中代码偏移量的差异是结构布局差异的证据。由于编译器、汇编程序和链接器版本以及优化设置的不同,代码布局可以很容易地更改。
共享对象可能只是使用结构的不同定义。使用您发布的定义,您将不得不使用类似于#pragma pack的东西来创建不同的布局,这似乎不太可能是原因。
编辑我错过了struct stat成员。这实际上是一个no-no,因为它会根据_FILE_OFFSET_BITS的值(比如ino_t和off_t)来改变大小。可移植代码不应在公共头文件中使用这些类型(和time_t)。
https://stackoverflow.com/questions/47242225
复制相似问题