dlsym can't use handle returned by dlopen?

Jeremy Chadwick koitsu at FreeBSD.org
Wed Nov 12 20:29:16 PST 2008

On Thu, Nov 13, 2008 at 12:59:27AM +0100, Markus Hoenicka wrote:
> FreeBSD yeti.mininet 6.1-RELEASE FreeBSD 6.1-RELEASE #1: Mon Aug 28 22:24:48 CEST 2006     markus at yeti.mininet:/usr/src/sys/i386/compile/YETI  i386
> I'm trying to do the following: libdbi (http://libdbi.sourceforge.net)
> is a database abstraction layer which is linked as a shared object
> into applications. The libdbi library uses dlopen() to load database
> drivers which in turn are linked against database client
> libraries. Now I want to access functions defined in the database
> client library from within the libdbi library. In brief, I thought
> this is going to work like this:
> dlhandle = dlopen("path", RTLD_NOW);
> ...
> function_pointer = dlsym(dlhandle, "function_name");
> dlhandle is not NULL and does not crash the app when passed to
> dlclose(), so I assume the handle is valid. Accessing the functions
> does work on most systems (Linux, OSX, Cygwin, to name a few), but I
> get "Undefined symbol" errors on FreeBSD. Interestingly, the following
> does work:

I've personally used dlopen() and dlsym(), and they do work as
documented (my original goal with bsdhwmon was to keep each chip in a
separate .so.  It worked, but added complexities of the program nature
itself kept me from using it at the time).  I tested this on both i386
and amd64.

I know that the .so's you're loading with dlopen() need to be built a
specific way/with certain arguments, otherwise they won't work (I
believe what I saw was dlsym() returning NULL).  My symbol names were
getting stomped on, and there was a compiler flag that addressed that.

I can go back and write code that does all of this if you'd like, but my
point is that they do work.

> function_pointer = dlsym(RTLD_DEFAULT, "function_name");
> Why is that? Or rather: what am I doing wrong?

This code right here is *completely* wrong.  RTLD_DEFAULT is a mode bit
for dlopen().  I'm willing to bet a strict set of warnings would
catch this.  Try building your application with:

-g3 -ggdb -Werror -Wall -Wunused -Waggregate-return -Wbad-function-cast
-Wcast-align -Wdeclaration-after-statement -Wdisabled-optimization
-Wfloat-equal -Winline -Wmissing-declarations -Wmissing-prototypes
-Wnested-externs -Wold-style-definition -Wpacked -Wpointer-arith
-Wredundant-decls -Wsign-compare -Wstrict-prototypes -Wunreachable-code

And see what appears.

| Jeremy Chadwick                                jdc at parodius.com |
| Parodius Networking                       http://www.parodius.com/ |
| UNIX Systems Administrator                  Mountain View, CA, USA |
| Making life hard for others since 1977.              PGP: 4BD6C0CB |

More information about the freebsd-questions mailing list