On Thu, Jan 23, 2014 at 3:12 PM, Eric Anholt <e...@anholt.net> wrote: > Steam links against libudev.so.0, while we're linking against > libudev.so.1. The result is that the symbol names (which are the same in > the two libraries) end up conflicting, and some of the usage of .so.1 > calls the .so.0 bits, which have different internal structures, and > segfaults happen. > > By using a dlopen() with RTLD_LOCAL, we can explicitly look for the > symbols we want, while they get the symbols they want.
Less painful than I thought it'd be, nice. Reviewed-by: Kristian Høgsberg <k...@bitplanet.net> > --- > configure.ac | 2 +- > src/egl/main/Makefile.am | 2 +- > src/loader/Makefile.am | 5 +---- > src/loader/loader.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 45 insertions(+), 6 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 33ac922..d266d96 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -858,7 +858,7 @@ xyesno) > > if test x"$enable_dri3$have_libudev" = xyesyes; then > X11_INCLUDES="$X11_INCLUDES $LIBUDEV_CFLAGS" > - GL_LIB_DEPS="$GL_LIB_DEPS $LIBUDEV_LIBS" > + GL_LIB_DEPS="$GL_LIB_DEPS" > fi > > # need DRM libs, $PTHREAD_LIBS, etc. > diff --git a/src/egl/main/Makefile.am b/src/egl/main/Makefile.am > index 60cb600..e12aeae 100644 > --- a/src/egl/main/Makefile.am > +++ b/src/egl/main/Makefile.am > @@ -112,7 +112,7 @@ if HAVE_EGL_DRIVER_DRI2 > AM_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2 > AM_CFLAGS += -DHAVE_XCB_DRI2 > libEGL_la_LIBADD += ../drivers/dri2/libegl_dri2.la > -libEGL_la_LIBADD += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIBS) > +libEGL_la_LIBADD += $(DLOPEN_LIBS) $(LIBDRM_LIBS) > endif > > # Provide compatibility with scripts for the old Mesa build system for > diff --git a/src/loader/Makefile.am b/src/loader/Makefile.am > index 371dd57..bddf7ac 100644 > --- a/src/loader/Makefile.am > +++ b/src/loader/Makefile.am > @@ -29,9 +29,6 @@ libloader_la_CPPFLAGS = \ > $(VISIBILITY_CFLAGS) \ > $(LIBUDEV_CFLAGS) > > -libloader_la_LIBADD = \ > - $(LIBUDEV_LIBS) > - > if !HAVE_LIBDRM > libloader_la_CPPFLAGS += \ > -D__NOT_HAVE_DRM_H > @@ -39,7 +36,7 @@ else > libloader_la_CPPFLAGS += \ > $(LIBDRM_CFLAGS) > > -libloader_la_LIBADD += \ > +libloader_la_LIBADD = \ > $(LIBDRM_LIBS) > endif > > diff --git a/src/loader/loader.c b/src/loader/loader.c > index a5bd769..63b977a 100644 > --- a/src/loader/loader.c > +++ b/src/loader/loader.c > @@ -67,6 +67,8 @@ > #include <stdarg.h> > #include <stdio.h> > #include <string.h> > +#include <assert.h> > +#include <dlfcn.h> > #include "loader.h" > > #ifndef __NOT_HAVE_DRM_H > @@ -92,11 +94,37 @@ static void (*log_)(int level, const char *fmt, ...) = > default_logger; > #ifdef HAVE_LIBUDEV > #include <libudev.h> > > +static void *udev_handle = NULL; > + > +static void * > +udev_dlopen_handle(void) > +{ > + if (!udev_handle) { > + udev_handle = dlopen("libudev.so.1", RTLD_LOCAL | RTLD_LAZY); > + } > + > + return udev_handle; > +} > + > +static void * > +asserted_dlsym(void *dlopen_handle, const char *name) > +{ > + void *result = dlsym(dlopen_handle, name); > + assert(result); > + return result; > +} > + > +#define UDEV_SYMBOL(ret, name, args) \ > + ret (*name) args = asserted_dlsym(udev_dlopen_handle(), #name); > + > + > static inline struct udev_device * > udev_device_new_from_fd(struct udev *udev, int fd) > { > struct udev_device *device; > struct stat buf; > + UDEV_SYMBOL(struct udev_device *, udev_device_new_from_devnum, > + (struct udev *udev, char type, dev_t devnum)); > > if (fstat(fd, &buf) < 0) { > log_(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d", fd); > @@ -119,6 +147,14 @@ loader_get_pci_id_for_fd(int fd, int *vendor_id, int > *chip_id) > struct udev *udev = NULL; > struct udev_device *device = NULL, *parent; > const char *pci_id; > + UDEV_SYMBOL(struct udev *, udev_new, (void)); > + UDEV_SYMBOL(struct udev_device *, udev_device_get_parent, > + (struct udev_device *)); > + UDEV_SYMBOL(const char *, udev_device_get_property_value, > + (struct udev_device *, const char *)); > + UDEV_SYMBOL(struct udev_device *, udev_device_unref, > + (struct udev_device *)); > + UDEV_SYMBOL(struct udev *, udev_unref, (struct udev *)); > > *chip_id = -1; > > @@ -240,6 +276,12 @@ loader_get_device_name_for_fd(int fd) > struct udev *udev; > struct udev_device *device; > const char *const_device_name; > + UDEV_SYMBOL(struct udev *, udev_new, (void)); > + UDEV_SYMBOL(const char *, udev_device_get_devnode, > + (struct udev_device *)); > + UDEV_SYMBOL(struct udev_device *, udev_device_unref, > + (struct udev_device *)); > + UDEV_SYMBOL(struct udev *, udev_unref, (struct udev *)); > > udev = udev_new(); > device = udev_device_new_from_fd(udev, fd); > -- > 1.8.5.3 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev