On 2007-12-30 18:49, Markus Hoenicka <markus.hoenicka mhoenicka.de> 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.sourcefor
ge.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/pipermai
l/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
%sn", mod);
% exit(1);
% }
%
% (void*) InitializeMagick = dlsym( handle,
"InitializeMagick");
% if ( !InitializeMagick) {
% fprintf( stderr, "cannot resolve
InitializeMagickn");
% 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 freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|