This is the mail archive of the
mailing list for the GCC project.
Re: Cancelling atexit calls
- To: Martin von Loewis <martin at mira dot isdn dot cs dot tu-berlin dot de>
- Subject: Re: Cancelling atexit calls
- From: Roland McGrath <roland at frob dot com>
- Date: Sun, 6 Sep 1998 16:54:52 -0400
- Cc: libc-alpha at gnu dot org, egcs-patches at cygnus dot com
- Emacs: because editing your files should be a traumatic experience.
> a) Destructors need to run in exact reverse order of construction;
> this holds even for destructors of static block-locals (for which
> the initialization order is not known at compile time).
> b) Destructors in C++ need to interleave with atexit functions:
> If a call to atexit was made between the construction of two
> globals, that function needs to be called between the destructors.
I see. Are these behaviors specified by the C++ standard? (If not, I
submit that this whole mess is not worth worrying about, since C++ programs
should not rely on the implementation calling destructors in any particular
order except as mandated by the standard.)
> > As well as questioning the need for it, I am concerned about your new
> > interface. An ill-specified `token' address could be overloaded by
> > different parties. Make them take a `void **', the address of a location
> > provided by the caller and initialized to 0 before the first call to
> > `atexitc'; that is still fairly simple to use, and makes it easy for the
> > implementation to just store there a pointer to the data structure it
> > allocates.
> This is a good idea.
I'm glad you like it. With this approach, there is no need to worry about
any of the dynamic linking issues you raised (though I address them below
for your information).
> > Also, `atexitc' is not a very good name.
> This name tries to suggest 'at exit unless canceled'. Please propose
> a different name.
I am not good with names, but I'm sure that appending a single letter to an
ANSI/ISO standard C function name produces a bad choice for a name.
> > You cannot assume that a reference in a given shared object gets the
> > value defined in that shared object (unless you linked it with
> > -symbolic).
> This is what I found. I still think it is unfortunate.
Please trust us who know the shared library implementation in great detail
that this is a fundamentally necessary behavior for correct functionality.
These are not the droids you're looking for.
> > You can use _GLOBAL_OFFSET_TABLE_.
> > That symbol is magic and causes the assembler to produce a special reloc.
> > (At least I think it still works this way.)
> I'm a bit worried about portability here. If I have gcc generate
> references to _GLOBAL_OFFSET_TABLE_, how do I know whether the
> assembler does the right thing? It seems that the special-reloc thing
> is performed only on i386.
Don't use it; even if portable, it's unnecessary hair.
Any given text address in the shared library will suffice as unique pointer
while the library is loaded. You could use the address of the function you
are registering, or whatever; if it's a local symbol (i.e. define the
finalizer function static in the same file as the initializer that
registers it), then the run-time address you get will always be the one in
that shared object. There is no need to pick a single magic symbol like _end.
Anyway, with the interface I proposed and you seem to like, there is no
need for any of this nonsense. The only "hook" required is the address of
a `void *' variable in the shared object's data/bss segment; that need
never be a global variable at all, so no symbol naming issues arise
> Also, under your proposed interface, how could I get a reference
> to a variable with exactly one copy per shared library?
I don't understand what you are referring to. There is no shared library
magic at all in what I suggest. Callers of `atexitc' (or whatever it gets
renamed) et al are reponsible for providing a `void *' location where the
list of functions will be stored.