From owner-freebsd-questions@FreeBSD.ORG Mon Dec 31 10:46:36 2007 Return-Path: Delivered-To: FreeBSD-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1BABD16A477 for ; Mon, 31 Dec 2007 10:46:36 +0000 (UTC) (envelope-from keramida@ceid.upatras.gr) Received: from igloo.linux.gr (igloo.linux.gr [62.1.205.36]) by mx1.freebsd.org (Postfix) with ESMTP id 8F62F13C458 for ; Mon, 31 Dec 2007 10:46:35 +0000 (UTC) (envelope-from keramida@ceid.upatras.gr) Received: from kobe.laptop (ppp5-162.adsl.forthnet.gr [62.1.228.162]) (authenticated bits=128) by igloo.linux.gr (8.14.1/8.14.1/Debian-9) with ESMTP id lBVAkHaZ031974 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Mon, 31 Dec 2007 12:46:26 +0200 Received: from kobe.laptop (kobe.laptop [127.0.0.1]) by kobe.laptop (8.14.2/8.14.2) with ESMTP id lBVAkGI7001930; Mon, 31 Dec 2007 12:46:16 +0200 (EET) (envelope-from keramida@ceid.upatras.gr) Received: (from keramida@localhost) by kobe.laptop (8.14.2/8.14.2/Submit) id lBVAkFe2001929; Mon, 31 Dec 2007 12:46:15 +0200 (EET) (envelope-from keramida@ceid.upatras.gr) Date: Mon, 31 Dec 2007 12:46:15 +0200 From: Giorgos Keramidas To: Markus Hoenicka Message-ID: <20071231104614.GA1761@kobe.laptop> References: <18295.55864.740395.631672@yeti.mininet> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <18295.55864.740395.631672@yeti.mininet> X-Hellug-MailScanner: Found to be clean X-Hellug-MailScanner-SpamCheck: not spam, SpamAssassin (not cached, score=-4.043, required 5, autolearn=not spam, ALL_TRUSTED -1.80, AWL 0.36, BAYES_00 -2.60) X-Hellug-MailScanner-From: keramida@ceid.upatras.gr X-Spam-Status: No Cc: FreeBSD-questions@freebsd.org Subject: Re: dlopen(), atexit() on FreeBSD X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Dec 2007 10:46:36 -0000 On 2007-12-30 18:49, Markus Hoenicka 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 % #include % % 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