Re: dlopen()ing shared libraries considered harmful (was Re: Depends/Recommends from libraries)
- Date: Sun, 26 Mar 2017 09:37:54 +0200
- From: Florian Weimer <fw@xxxxxxxxxxxxx>
- Subject: Re: dlopen()ing shared libraries considered harmful (was Re: Depends/Recommends from libraries)
* Guillem Jover:
>> dlopen()ing dependencies in the way that is most commonly implemented,
>> with dlopen("libimobiledevice.so.6") and dlsym(handle, "idevice_new")
>> or similar, has some practical problems for Debian:
>> * The libraries used aren't visible to dpkg-shlibdeps. The maintainer has
>> to know what dlopen() calls the code will make, and either hard-code an
>> appropriate Depends (or in this case Recommends), or link a dummy
>> executable against the same things that are dlopen()ed (as is done
>> in packages like wine and openal-soft) and use that for dpkg-shlibdeps.
>> Either way, they have to remember to update it for every new upstream
>> release. This is the sort of tedious-but-subtle work that we automate
>> because otherwise it will inevitably be incorrect after a few releases.
>> * The exact symbols used aren't visible to dpkg-shlibdeps. The maintainer
>> has to hard-code a version number that has all the required symbols.
>> Again, this is the sort of thing that we automate because it will
>> inevitably go wrong if done manually.
> * Because the shared library SONAME is hard-coded in both code and
> packaging metadata, whenever there's a transition with a SOVERSION
> bump that could have been handled with a simple mass binNMU, instead
> it requires manual intervention to patch those, while making sure it
> still works due to the points above.
* For regular dynamic linking, the static linker (ld) puts the default
symbol version seen in the linked DSO into the object which refers
to that DSO, so that each symbol refers to a fixed symbol version.
This symbol version matches the header file contents of the library
at the time, and is consistent with the link. With dlopen/dlsym,
this step does not happen, and dlsym will pick the newest (*) symbol
version. This version might not match what was in the header files
at compilation time. (Theoretically, it would be possible to
determine the applicable symbol version at compile time and use
dlvsym, but no one does that.)
(*) Not quite because we have a bug:
>> The pedantically correct way to have weak library dependencies is this
>> multi-level chain of linking, analogous to what is documented for APIs
>> that wrap dlopen() such as libltdl and GLib's GModule:
>> - eventual API user, e.g. /usr/bin/gnome-software
>> - a plugin intended to be dlopen()ed, e.g. libgs_plugin_flatpak-user.so
>> has DT_NEEDED on:
>> - libflatpak0
> I don't think this is pedantical at all, it's IMO the only sane and
> correct way to handle this.
Right, this way also allows the static linker to do its job and fix
the symbol version.