首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哪些编译器/链接器选项会影响结构在内存中的布局方式?

哪些编译器/链接器选项会影响结构在内存中的布局方式?
EN

Stack Overflow用户
提问于 2017-11-11 19:59:28
回答 2查看 55关注 0票数 0

摘要:,我正在试图找出编译器中的哪些设置会改变内存中结构设置的方式

详细信息:I有两个版本的同一个库文件(libgbm.so),一个作为预建的二进制文件提供,另一个在我自己的机器上编译。一个正确工作,另一个抛出分段错误。看来我的编译器处理数据结构的方式与预编译版本不同.

我已经提供了一个精简版本的代码(请参阅底部的相关结构)。基本上,它加载一个共享库并调用create_device()函数。它返回带有一串函数指针的数据结构(gbm_device)。

代码语言:javascript
复制
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之后的下一步

代码语言:javascript
复制
0xb6beb5d0 in ?? () from /usr/lib/gbm/gbm_pvr.so

当使用我的本地编译版本时,GDB显示下一步如下

代码语言:javascript
复制
0xb6c414a4 in ?? () from /usr/lib/gbm/gbm_pvr.so

我没有用于gbm_pvr.so (专有库)的调试符号,但是代码显然进入了两个不同的函数(至少内存地址的最后3位数字应该是相同的)。

我唯一能想到的是,我忽略了一些编译器/链接器设置,它改变了gbm_device结构在内存中的布局方式,从而扰乱了它获得的所有指针。

下面是关联结构

代码语言:javascript
复制
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);
};

代码语言:javascript
复制
struct gbm_backend {
   const char *backend_name;
   struct gbm_device *(*create_device)(int fd);
};
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-12 19:11:17

我解决了问题。

我的构建环境自动添加了以下编译器标志。移除这些问题解决了问题。

代码语言:javascript
复制
-D_LARGEFILE_SOURCE
-D_LARGEFILE64_SOURCE
-D_FILE_OFFSET_BITS=64 
票数 0
EN

Stack Overflow用户

发布于 2017-11-11 21:01:12

我不认为页面中代码偏移量的差异是结构布局差异的证据。由于编译器、汇编程序和链接器版本以及优化设置的不同,代码布局可以很容易地更改。

共享对象可能只是使用结构的不同定义。使用您发布的定义,您将不得不使用类似于#pragma pack的东西来创建不同的布局,这似乎不太可能是原因。

编辑我错过了struct stat成员。这实际上是一个no-no,因为它会根据_FILE_OFFSET_BITS的值(比如ino_toff_t)来改变大小。可移植代码不应在公共头文件中使用这些类型(和time_t)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47242225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档