[Info-vax] Shared Objects And DLL Hell
Richard Levitte
richard at levitte.org
Thu Jun 30 18:13:28 EDT 2016
Den torsdag 30 juni 2016 kl. 08:06:10 UTC+2 skrev lawren... at gmail.com:
> I saw some discussion elsewhere on why Microsoft Windows is prone to “DLL Hell”, and whether Linux had a similar problem.
>
> Linux has shareable libraries (“Dynamic Shared Objects” or DSOs, I believe is the official term) in the form of .so files. I think it avoids DLL hell because of two reasons:
> * library versioning to cope with backward-incompatible ABI changes, and
> * package management
>
> That is, a shareable library comes from a distro-provided package. Other packages that require that library declare a dependency on that package, which can also specify required versions. So the package manager ensures that installed packages form a consistent dependency graph.
>
> Library versioning is done by sticking a version number after the .so extension. For example, just browsing through my own system, I came across the following:
>
> root at theon:~ # ls -l /usr/lib/x86_64-linux-gnu/
> ...
> lrwxrwxrwx 1 root root 20 Jun 23 01:28 libapt-inst.so -> libapt-inst.so.2.0.0
> lrwxrwxrwx 1 root root 20 May 23 2015 libapt-inst.so.1.5 -> libapt-inst.so.1.5.0
> -rw-r--r-- 1 root root 63360 May 23 2015 libapt-inst.so.1.5.0
> lrwxrwxrwx 1 root root 20 Jun 23 01:28 libapt-inst.so.2.0 -> libapt-inst.so.2.0.0
> -rw-r--r-- 1 root root 51280 Jun 23 01:30 libapt-inst.so.2.0.0
> ...
>
> Those files “libapt-inst.so.1.5.0” and “libapt-inst.so.2.0.0” come from two entirely different packages with two different names, not two versions of the same package, which I have installed at the same time:
>
> root at theon:~ # dpkg-query -S /usr/lib/x86_64-linux-gnu/libapt-inst.so.1.5.0
> libapt-inst1.5:amd64: /usr/lib/x86_64-linux-gnu/libapt-inst.so.1.5.0
> root at theon:~ # dpkg-query -S /usr/lib/x86_64-linux-gnu/libapt-inst.so.2.0.0
> libapt-inst2.0:amd64: /usr/lib/x86_64-linux-gnu/libapt-inst.so.2.0.0
>
> This way, other packages that depend on the older ABI can coexist with those that need the newer one.
>
> Note the symlinks: a bugfix to version 2.0.1 could produce a new library “libapt-inst.so.2.0.1", which would be installed under its own name. The symlink “libapt-inst.so.2.0” can then be updated to point to 2.0.1 instead of 2.0.0, and executables (and other libraries) using the “2.0” name will automatically pick up the new version.
It's not that simple. Exactly what file name is being written into the application depends on a string called SONAME in the library, which gets copied to the NEEDED strings in the applications linked with that library.
Here's an example, the library libdl:
: ; ls -l /usr/lib/x86_64-linux-gnu/libdl.*
-rw-r--r-- 1 root root 12754 jun 27 02:37 /usr/lib/x86_64-linux-gnu/libdl.a
lrwxrwxrwx 1 root root 32 jun 27 02:37 /usr/lib/x86_64-linux-gnu/libdl.so -> /lib/x86_64-linux-gnu/libdl.so.2
: ; ls -l /lib/x86_64-linux-gnu/libdl.so.2
lrwxrwxrwx 1 root root 13 jun 27 02:36 /lib/x86_64-linux-gnu/libdl.so.2 -> libdl-2.22.so
: ; ls -l /lib/x86_64-linux-gnu/libdl-2.22.so
-rw-r--r-- 1 root root 14640 jun 27 02:37 /lib/x86_64-linux-gnu/libdl-2.22.so
So, when building your application using something like -ldl, the linker will go through that series of symlinks until it gets to libdl-2.22.so. The SONAME is this:
: ; LANG=C readelf -d /lib/x86_64-linux-gnu/libdl-2.22.so | grep SONAME
0x000000000000000e (SONAME) Library soname: [libdl.so.2]
So now, let's have a look at a program that uses libdl:
: ; LANG=C readelf -d /usr/bin/openssl | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libssl.so.1.0.2]
0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.1.0.2]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
See how the stored name is libdl.so.2? That's the file name, and really the only file name that the dynamic loader will look for when starting the program. No more magic than that. All other file names to the same library are just convenience...
Cheers,
Richard
P.S. LANG=C because I run my terminals with swedish locale. I thought english would be more convenient here ;-)
More information about the Info-vax
mailing list