https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500

R. Diez <rdiezmail-gcc at yahoo dot de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|DUPLICATE                   |FIXED

--- Comment #13 from R. Diez <rdiezmail-gcc at yahoo dot de> ---
>From your comments about "constexpr constructor" and "constinit", I gather that
the "eh_globals" singleton is guaranteed then to be initialised very early,
earlier than anything else that might use it, right? But that does not
guarantee that it will be destroyed later than anything that wants to use it,
is that correct? That is why we need the hack, to make it outlive all potential
users.

I am now trying to understand the implications of not destroying
"__cxa_eh_globals obj" inside the "eh_globals" singleton, at least in the case
of single-threaded (bare metal) embedded software. Hopefully, I can learn a
little more along the way about how C++ exception handling works.

As far as I can see, "struct __cxa_eh_globals" in unwind-cxx.h has 1 or 2
pointers and no destructor:

struct __cxa_eh_globals
{
  __cxa_exception *caughtExceptions;
  unsigned int uncaughtExceptions;
#ifdef __ARM_EABI_UNWINDER__
  __cxa_exception* propagatingExceptions;
#endif
};

Therefore, destroying this object should have real no effect. I wonder why
there was a problem to fix in 'eh_globals' then.

I am guessing that some static analyser, or checker instrumentation, may now
complain that static object 'eh_globals', or at least its member 'obj', has not
been properly destroyed upon termination. Normally, that would mean a risk of
leaking some memory, but I am guessing that the last thread can never have any
such 'caughtExceptions' or 'propagatingExceptions' left upon termination,
right?

So, theoretically, instead of leaving the destructor for the singleton empty,
we could add asserts that those 2 pointers are nullptr. Or am I missing
something?

This all feels iffy. If I understand this correctly, it is impossible for GCC
to guarantee the correct construction and destruction order of such global
objects, and that is why we are hacking our way out. The reason is mainly, that
not all targets support "__attribute__ constructor", so there is no way to
implement a deterministic initialisation and destruction order for everybody.
Is that right?

Reply via email to