This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

__cxa_finalize/__dso_handle contract

I'm working on crtbegin.o/crtend.o implementation for compiler-rt as
part of the LLVM project (see for more

One suggestions that was raised in the review
( is to stop differentiating
between the shared and non-shared case (i.e. no crtbeginS.o) and
instead use the same object for both cases. The implication of this
change is that we would use

void *__dso_handle = &__dso_handle;

instead of

void *__dso_handle = (void *)0;

for the non-shared case. I've checked different libc implementations,
and AFAICT glibc is the only one that differentiates between the two
cases in its __cxa_finalize implementation.

In glibc's __cxa_finalize(void *d), a nonzero d has to match the value
passed to __cxa_atexit but a zero d matches every function registered.
So it matters that DSO fini calls use &__dso_handle to match their
registrations for the dlclose case, but it also matters that the main
executable fini call (i.e. exit itself, and resp. for quick_exit) use
zero to run all the dtors at exit time.

However, it's not clear whether it needs to be that way, because DSO
fini should run at exit time too, but it would be a change of how the
dtors get run that might affect dtor order in some cases.

So my question is whether the dtor order is something that glibc users
should rely on or whether this is considered (an unsupported) corner
case and whether the suggested change to always use nonzero d even for
main executable would break the existing contract between __dso_handle
and __cxa_finalize for glibc?

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]