dlopen(), atexit() crash on FreeBSD (testcase included)

John Baldwin jhb at freebsd.org
Mon Dec 31 14:35:39 PST 2007


On Monday 31 December 2007 05:20:51 pm Julian Elischer wrote:
> Markus Hoenicka wrote:
> > Alexander Kabaev writes:
> >  > As designed. atexit should not be used by shared objects that do not
> >  > expect themselves to live until actual exit() happens. ELF provides
> >  > proper _init/_fini sections to support shared object
> >  > initialization/destruction.
> >  > 
> > 
> > That is, the only real solution to this problem is to convince the
> > Firebird folks to remove their atexit() calls from the client
> > libraries? I'll try, but I'm not very confident this is going to
> > work. Also, I'm wondering how other OSes handle this. I don't see this
> > code crash on Linux, contrary to its design as you say.
> > 
> > Thanks anyway to you, and to Jason Evans, for your replies.
> 
> Not sure but I'd guess that each library calls its at_exit entrypoints
> as part of its unload handling.

Older gcc used to use atexit() for destructors (2.95.x for example) but newer 
versions of gcc use fini routines.  We have a hack in the run time linker 
that walks the atexit() list for 4.x binaries and manually pulls out any 
routines in the mapped region of a shared object during dlclose() to invoke 
the destructors and fixup the atexit list.  However, newer binaries don't 
need this.  If you used a regular old static C++ singleton on 6.x instead of 
trying to be cute and call atexit() directly you would be fine.  I've no idea 
if Linux treats atexit() special.

The documentation below for atexit() is very clear that handlers are only 
invoked for normal program termination, not for dlclose(), so you definitely 
have buggy code.

http://www.opengroup.org/onlinepubs/009695399/functions/atexit.html

-- 
John Baldwin


More information about the freebsd-hackers mailing list