Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Nov 2008 00:07:52 GMT
From:      Markus Hoenicka <markus.hoenicka@mhoenicka.de>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/129031: Portability issue: accessing symbols in shared objects via dlsym()
Message-ID:  <200811210007.mAL07qxS099597@www.freebsd.org>
Resent-Message-ID: <200811210010.mAL0A424024185@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         129031
>Category:       misc
>Synopsis:       Portability issue: accessing symbols in shared objects via dlsym()
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Nov 21 00:10:04 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Markus Hoenicka
>Release:        6.1-RELEASE
>Organization:
>Environment:
FreeBSD yeti.mininet 6.1-RELEASE FreeBSD 6.1-RELEASE #1: Mon Aug 28 22:24:48 CEST 2006     markus@yeti.mininet:/usr/src/sys/i386/compile/YETI  i386
>Description:
libdbi (http://libdbi.sourceforge.net) is a database abstraction layer provided as a shared object. libdbi uses dlopen() to load database engine drivers at runtime. Each of these drivers is linked against the client library of it's database engine:

app (linked to) libdbi (dlopens) driver (linked to) client library

Now libdbi is supposed to provide access to functions defined in the client libraries. To this end, dlsym is called with the function's name as the second argument. Unfortunately FreeBSD (and maybe other BSDs) differs from other systems in what may be passed to dlsym as the first argument:

If I pass the handle returned by dlopen() to dlsym(), the call fails.
If I pass RTLD_NEXT to dlsym(), the call succeeds.

If I try the same on other systems (OSX, Linux, Cygwin), the inverse is true:

If I pass the handle returned by dlopen() to dlsym(), the call succeeds.
If I pass RTLD_NEXT to dlsym(), the call fails.

Question is, is this a bug or a feature (in either system)? Are there better ways to arrive at a portable application than checking for the host type in configure?

>How-To-Repeat:
A test kit containing 4 source files and a Makefile is available here:

http://libdbi.sourceforge.net/downloads/dlsymtest.tar.gz

The kit builds straight on FreeBSD. To build it on Linux or other non-BSD systems, add -ldl in the Makefile as indicated by a comment.

To run the test app, use:

LD_LIBRARY_PATH=. ./myprog

The output on FreeBSD reads:

myint = 0xdeadbeef (3735928559)
==> entered myfunc()
==>     double = 3.141590
==>zlib version is 1.2.2
==> exiting myfunc()
dlsym() using dlopen handle failed: Undefined symbol "zlibVersion"
dlsym() using RTLD_NEXT succeeded

Note that the "driver" (myshared.so) uses zlibVersion() to retrieve the version number. However, the "library" (mylib.so) cannot access this function if the handle returned by dlopen() is used.

The output on Linux (Debian 4 using kernel 2.6.24) reads:
myint = 0xdeadbeef (3735928559)
==> entered myfunc()
==>     double = 3.141590
==>zlib version is 1.2.2
==> exiting myfunc()
dlsym() using dlopen handle succeeded
dlsym() using RTLD_NEXT failed: (null)


>Fix:


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811210007.mAL07qxS099597>