什么构建环境差异导致mesa GBM库的行为不同

时间:2017-11-09 15:22:05

标签: build compilation linker shared-libraries mesa

我正在开发一个基本的演示应用程序(kmscube)来通过DRM和GBM API进行渲染。我的应用程序使用libgbm的TI变体(mesa通用缓冲区管理)。 TI提供sourceGNU autotools filesbuild environment(Yocto)来编译它。我在他们的环境中编译了GBM,它运行得很好。

我不想使用Yocto,所以我将源代码移动到我自己的构建系统(buildroot)并编译它。一切都正确编译(使用相同的autotools文件),但是当它运行时,我调用gbm_surface_create时会出现分段错误。我尽可能调试,发现程序进入gbm库但在return gbm->surface_create(gbm, width, height, format, flags);上失败

在不同环境中编译时,导致库运行方式不同的原因。是否有一些我可能遗漏的非常重要的编译器或链接器标志?

这是图形应用程序中的代码(在kmscube.c

gbm.dev = gbm_create_device(drm.fd);

gbm.surface = gbm_surface_create(gbm.dev,
                                  drm.mode[DISP_ID]->hdisplay, drm.mode[DISP_ID]->vdisplay,
                                  drm_fmt_to_gbm_fmt(drm.format[DISP_ID]),
                                  GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
if (!gbm.surface) {
   printf("failed to create gbm surface\n");
   return -1;
}

return 0;

这是创建设备的调用堆栈(在gbm.c

GBM_EXPORT struct gbm_device *
gbm_create_device(int fd)
{
   struct gbm_device *gbm = NULL;
   struct stat buf;

   if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) {
      fprintf(stderr, "gbm_create_device: invalid fd: %d\n", fd);
      return NULL;  
   }

   if (device_num == 0)
      memset(devices, 0, sizeof devices);

   gbm = _gbm_create_device(fd);
   if (gbm == NULL)
      return NULL;

   gbm->dummy = gbm_create_device;
   gbm->stat = buf;
   gbm->refcount = 1;

   if (device_num < ARRAY_SIZE(devices)-1)
      devices[device_num++] = gbm;

   return gbm;
}

(继续backend.c

struct gbm_device *
_gbm_create_device(int fd)
{
   const struct gbm_backend *backend = NULL;
   struct gbm_device *dev = NULL;
   int i;
   const char *b;

   b = getenv("GBM_BACKEND");
   if (b)
      backend = load_backend(b);

   if (backend)
      dev = backend->create_device(fd);

   for (i = 0; i < ARRAY_SIZE(backends) && dev == NULL; ++i) {
      backend = load_backend(backends[i]);
      if (backend == NULL)
         continue;
      fprintf(stderr, "found valid GBM backend : %s\n", backends[i]);
      dev = backend->create_device(fd);
   }

   return dev;
}

static const void *
load_backend(const char *name)
{
   char path[PATH_MAX];
   void *module;
   const char *entrypoint = "gbm_backend";

   if (name[0] != '/')
      snprintf(path, sizeof path, MODULEDIR "/%s", name);
   else
      snprintf(path, sizeof path, "%s", name);

   module = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
   if (!module) {
      fprintf(stderr, "failed to load module: %s\n", dlerror());
      return NULL;
   }
   else {
      fprintf(stderr, "loaded module : %s\n", name);
   }

   return dlsym(module, entrypoint);
}

以下是抛出分段错误的代码(在gbm.c

GBM_EXPORT struct gbm_surface *
gbm_surface_create(struct gbm_device *gbm,
                   uint32_t width, uint32_t height,
                   uint32_t format, uint32_t flags)
{
   return gbm->surface_create(gbm, width, height, format, flags);
}

0 个答案:

没有答案