Re: BerkeleyDB Perl module on potato (slightly long)
[This is an edited resend of a mail to Paul Marquess, BerkeleyDB
author, which bounced (my own fault) when I wrote it last August and
neglected to resend. Paul, this issue came up on debian-perl, so
I'm Cc'ing there. Actually, it is only the second half of the
original message, which is all that is relevant here.]
I have some analysis on the Berkeley DB on Linux issue. I agree
that it is tricky, but I think you have mischaracterized it. The
problem is not that a version of Berkeley DB is included in the C
library. GNU libc does come with Berkeley DB, but it is in its own
shared library (libdb.so), and a trivial program linked with libc
will not use libdb at all (eg, "strace ls |& grep libdb" returns
nothing). Debian GNU/Linux has packages for alternate versions of
BerkeleyDB, and I verified that a test program can be linked against
them and run successfully with no interference from libc. (This
might not be true in all cases, however; I think some optional
features of GNU libc use libdb internally, such nss.)
The main problem seems to be that, on most Linux distributions,
programs by default link to libdb as a shared library, instead of as
a static library. For example, the link line for perl includes -ldb
on both Linux and Solaris, but this is harmless on Solaris since
libdb is typically static and perl itself doesn't use libdb, so no
symbols from libdb.a are linked in; whereas on Linux, this is a
problem, because it causes libc's dynamic version of libdb to be
loaded whenever perl starts. This makes a mess when you later try
to load the libdb to which BerkeleyDB is linked.
As often happens, while writing this mail I came up with a
workaround. When compiling your own Berkeley DB, compile it shared,
just like libc's libdb (this is done by "../dist/configure
--enable-dynamic"). Link BerkeleyDB.so against this shared libdb,
and when running perl, set LD_LIBRARY_PATH to point at the new
libdb. Then, perl and BerkeleyDB.so both load the same libdb.
[UPDATE: I think this will only work if the lidbd you compile has
the soname that perl wants, which isn't true if "the libdb you
compile" comes from the Debian libdb2 package. However, I
definitely did get the above to work when I originally wrote this.]
A less intrusive if uglier workaround allows you to keep
BerkeleyDB.so statically linked against libdb. If you convince perl
(actually, the dynamic linker when it loads perl) to load an empty
stub libdb.so, all will be well since perl doesn't actually use
Berkeley DB itself. You can create this stub with "touch foo.c; gcc
-shared -o libdb.so foo.c", and load it with
"LB_LIBRARY_PATH=/path/to/stub perl". Now, when you load
BerkeleyDB.so, which is statically linked to the new libdb.a, there
is no other version of libdb with which to conflict.
I think a clean solution would be to inhibit perl linking with libdb
in the first place, since it doesn't need it. I suspect the current
behavior is an artifact of the original perl support for Berkeley DB
more than anything else. I haven't tried this, but I bet if this
were done, the problem would never have arisen. Do you agree? How
hard do you think it would be to change the perl build process?
[UPDATE: The perl 5.6.0 in Debian testing doesn't linke to libdb.
Don't know whether this is a Debian change or a perl change, but it
should enable us to forget about this difficulty!]
Thanks for your work on BerkeleyDB. I'm looking forward to using
_all_ the features of Berkeley DB from Perl!
Andrew
Reply to: