On Wed, Mar 05, 2008 at 05:12:32PM -0800, Tim Kientzle wrote: > There was some recent discussion on the commit mailing > list about how to disentangle crt1.o from malloc(). > > Here's a design that I think addresses all of the > issues people raised, including the POSIX requirement > that atexit() always be able to support 32 registrations. > It does it without using sbrk() or mmap(), either. > > The basic idea is to lift the malloc() call up into > atexit() and have atexit_register() use statically-allocated > storage if atexit() didn't provide dynamically-allocated > storage. > > This basically changes atexit() to something like this pseudocode: > > int atexit(void (*function)(void)) > { > struct atexit *storage = malloc(sizeof(struct atexit)); > > /* Note: If malloc() fails, __atexit_register will try > * to statically allocate, so we don't check here > * for malloc() failure. */ > return __atexit_register(function, storage); > } > > Then atexit_register either uses the block that was provided > or grabs an item from a static pool if there wasn't one: > > /* 32 required by POSIX plus a few for crt1.o */ > static struct atexit pool[40]; > > int atexit_register(void (*function)(void), struct atexit *storage) > { > if (storage == NULL) { > storage = ... next item from static pool ... > } > storage.func = function; > ... add storage block to linked list ... > } > > Avoiding free() from the low-level code is a little trickier > but I think it can be done by having the low-level code > put (dynamically-allocated) blocks back onto a free list > and having the higher-level atexit() release that list > on the next registration. This should handle the case > of a dynamic library being repeatedly loaded and unloaded. > Of course, it's unnecessary to release the atexit storage > on program exit. > > In particular, crt1.o can then call atexit_register(f, NULL) > to register its exit functions without creating a dependency on > malloc. > > This does require that atexit() and atexit_register() be in > separate source files, but I think it addresses all of the other > concerns people have raised. I mostly agree with proposal, but there is also __cxa_atexit(). And, besides the issue of the size of the static linked executables, there is more exposed problem of atexit() memory leaks. See http://lists.freebsd.org/pipermail/freebsd-stable/2008-February/040644.html
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:28 UTC