Re: dlopen(), atexit() on FreeBSD
- From: Giorgos Keramidas <keramida@xxxxxxxxxxxxxxx>
- Date: Mon, 31 Dec 2007 12:46:15 +0200
On 2007-12-30 18:49, Markus Hoenicka <markus.hoenicka@xxxxxxxxxxxx> wrote:
Hi,
I bumped into a platform-specific problem when using the Firebird
database client library in a dlopen()ed module on FreeBSD. libdbi
(http://libdbi.sourceforge.net) is a database abstraction layer which
dlopen()s available database drivers at runtime to provide
connectivity to various database engines. This design works without
problems on a variety of platforms and with a variety of database
client libraries, but causes a segfault with Firebird on FreeBSD:
#0 0x28514fe4 in ?? ()
#1 0x281507c3 in __cxa_finalize () from /lib/libc.so.6
#2 0x281503fe in exit () from /lib/libc.so.6
#3 0x0804a40f in main (argc=1, argv=0xbfbfe754) at test_dbi.c:419
The application crashes when exit() is called. Googling told me that
__cxa_finalize () is invoked by atexit(). Our drivers and apps do not
use this function, but the firebird client libraries do:
markus@yeti:~/prog/libdbi-drivers/tests# grep atexit /usr/local/lib/libfb*
Binary file /usr/local/lib/libfbclient.so matches
Binary file /usr/local/lib/libfbembed.so matches
Googling also told me that the conflict between atexit() and dlopen()
on FreeBSD is a known problem, see e.g.:
http://www.imagemagick.org/pipermail/magick-developers/2006-March/002523.html
Is there anything I can do about this from my end?
The __cxa_finalize() function is not called by atexit(), but by exit()
itself. I don't know of any way to `unregister' exit handlers, so one
way of `fixing' this is to avoid calling dlclose() before exit() in the
example code shown at the URL above:
% #include <stdio.h>
% #include <dlfcn.h>
%
% int main( int argc, char ** argv)
% {
% void * handle;
% const char * mod = "/usr/local/lib/libMagick.so";
% void (*InitializeMagick)(const char*);
%
% handle = dlopen( mod, RTLD_LAZY);
% if ( !handle) {
% fprintf( stderr, "cannot load %s\n", mod);
% exit(1);
% }
%
% (void*) InitializeMagick = dlsym( handle, "InitializeMagick");
% if ( !InitializeMagick) {
% fprintf( stderr, "cannot resolve InitializeMagick\n");
% exit(1);
% }
%
% InitializeMagick( "moo");
% dlclose( handle);
% }
Since the program is going to exit and have all its dlopened shared
objects be unmapped, it's probably ok to skip the dlclose() step in
this example.
In the case of the firebird libraries, since they are libraries things
are a bit trickier, because the consumers of these libraries don't
really know that a dlopened object has called atexit() :(
I think this is probably something that the freebsd-hackers list will
be interested in. Can you post a description of the problem there too?
- Giorgos
_______________________________________________
freebsd-questions@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscribe@xxxxxxxxxxx"
- Follow-Ups:
- Re: dlopen(), atexit() on FreeBSD
- From: Markus Hoenicka
- Re: dlopen(), atexit() on FreeBSD
- References:
- dlopen(), atexit() on FreeBSD
- From: Markus Hoenicka
- dlopen(), atexit() on FreeBSD
- Prev by Date: Is it possible to mount OpenBSD FFS partitions in FreeBSD?
- Next by Date: Is it possible to mount OpenBSD FFS partitions in FreeBSD?
- Previous by thread: dlopen(), atexit() on FreeBSD
- Next by thread: Re: dlopen(), atexit() on FreeBSD
- Index(es):
Relevant Pages
|