Prefetch Technologies // Keeping your cache lines cozy

Perl module library madness!

While reading up on website performance monitoring applications last week, I came across the cricket HTTP-performance module. HTTP-performance allows you to graph the time it takes to connect to a website and to render a page. This sounded interesting, so I decided to download and install cricket. After reading through the beginners guide, I installed all of the required Perl modules, and proceeded to run the cricket compile script:

$ ./compile
Can't load '/usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so'
for module DB_File: ld.so.1: /usr/perl5/5.8.4/bin/perl: fatal: libdb-4.2.so:
open failed: No such file or
directory at /usr/perl5/5.8.4/lib/i86pc-solaris-64int/XSLoader.pm line 68.
at /usr/perl5/5.8.4/lib/i86pc-solaris-64int/DB_File.pm line 251
Compilation failed in require at
/home/rmatteso/cricket-1.0.5/lib/ConfigTree/Node.pm line 25.
BEGIN failed--compilation aborted at
/home/rmatteso/cricket-1.0.5/lib/ConfigTree/Node.pm line 25.
Compilation failed in require at ./compile line 39.
BEGIN failed--compilation aborted at ./compile line 39.I

Ack!!!! -- it looks like DB_File.so can't find the BerkelyDB shared library:

$ ldd
/usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so**

libdb-4.2.so => (file not found)
libc.so.1 => /lib/libc.so.1
libm.so.2 => /lib/libm.so.2

Since I hate using LD_LIBRARY_PATH, I decided to adjust the link line to include a hard coded runtime path. To determine which variable to edit, I searched the Makefile until I came to the following line:

$ less Makefile
$(LD) $(LDDLFLAGS) $(LDFROM) $(OTHERLDFLAGS) -o $@ $(MYEXTLIB) \
  $(PERL_ARCHIVE) $(LDLOADLIBS) $(PERL_ARCHIVE_AFTER) $(EXPORT_LIST) \
  $(INST_DYNAMIC_FIX)

After locating this line, I added "-R/usr/sfw/lib:/usr/local/BerkeleyDB/lib" to the LDDLFLAGS variable and rebuilt the Perl module:

$ make
cc -c -I/usr/local/BerkeleyDB/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_TS_ERR
NO -DVERSION="1.814" -DXS_VERSION="1.814"
"-I/usr/perl5/5.8.4/lib/i86pc-solaris-64
int/CORE" -D_NOT_CORE -DmDB_Prefix_t=size_t -DmDB_Hash_t=u_int32_t version.c
cc -c -I/usr/local/BerkeleyDB/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_TS_ERR
NO -DVERSION="1.814" -DXS_VERSION="1.814"
"-I/usr/perl5/5.8.4/lib/i86pc-solaris-64
int/CORE" -D_NOT_CORE -DmDB_Prefix_t=size_t -DmDB_Hash_t=u_int32_t DB_File.c
Running Mkbootstrap for DB_File ()
chmod 644 DB_File.bs
rm -f blib/arch/auto/DB_File/DB_File.so
LD_RUN_PATH="/usr/local/BerkeleyDB/lib"
cc -G -R/usr/sfw/lib:/usr/local/BerkeleyDB/lib version.o DB_File.o -o
blib/arch/auto/DB_File/DB_File.so -L/usr/local/BerkeleyDB/lib -ldb
chmod 755 blib/arch/auto/DB_File/DB_File.so
cp DB_File.bs blib/arch/auto/DB_File/DB_File.bs
chmod 644 blib/arch/auto/DB_File/DB_File.bs
Manifying blib/man3/DB_File.3
$ make install
Installing /usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so
Files found in blib/arch: installing files in blib/lib into architecture
dependent library tree
Installing /usr/perl5/5.8.4/man/man3/DB_File.3
Writing /usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/.packlist
Appending installation info to
/usr/perl5/5.8.4/lib/i86pc-solaris-64int/perllocal.pod

Everything seemed to work, but did the runpath get set correctly? A quick check revealed that it did:

$ dump -Lv
/usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so

/usr/perl5/5.8.4/lib/i86pc-solaris-64int/auto/DB_File/DB_File.so:

DYNAMIC SECTION INFORMATION
.dynamic:
[INDEX] Tag Value
[1] NEEDED libdb-4.2.so
[2] NEEDED libc.so.1
[3] INIT 0xe030
[4] FINI 0xe050
[5] RUNPATH /usr/sfw/lib:/usr/local/BerkeleyDB/lib
[6] RPATH /usr/sfw/lib:/usr/local/BerkeleyDB/lib

This was a fun experience, since it finally forced me to sit down and read through the ELF standard (great read if you are into that kind of stuff).