[cfe-dev] [RFC] Suppress C++ static destructor registration

David Chisnall via cfe-dev cfe-dev at lists.llvm.org
Tue Jul 17 00:15:25 PDT 2018


On 16 Jul 2018, at 22:55, JF Bastien via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> 
> Concrete example
> 
> Greg Parker provided this example of thread-related issues in the previous discussion:
> 
> The Objective-C runtime has a global table that stores retain counts. Pretty much all Objective-C code in the process uses this table. With global destructors in place this table is destroyed during exit(). If any other thread is still running Objective-C code then it will crash.
> 
> Currently the Objective-C runtime avoids the destructor by initializing this table using placement new into an aligned static char buffer.
> 
> I’m assuming that the embedded usecase is obvious enough to everyone to not need an example. Let me know if that’s not the case.

I have hit this issue a few times with similar solutions (either placement new, or simply new and leak the pointer), so I agree that this is a problem that needs solving.  That said, I rarely want to disable *all* static destructors, instead I want to either disable some or define ordering between them (which I can do by disabling some and explicitly calling them from another).

I would much prefer to see a [[no_destroy]] attribute or similar, to disable registering destructors for a specific static / global, than a different language mode.  I would also see a simplification of some code with a [[lazy_construct]] attribute so that I could declare a global and have it follow the same initialisation rules as a static, rather than having to create a static and a function that returns a reference to it.

I would; however, point out that exit() is not the only time that static destructors are run.  The C++ standard pretends that shared libraries don’t exist (and added thread-local variables with nontrivial destructors in such a way that gives implementers two possible bad choices if they have to support library unloading), but in the real world they do.  It’s difficult to see how such a mode would coexist with a world that supports loading and unloading of shared libraries.  Perhaps a sanitiser could check that the objects have been destroyed when the library is unloaded?

David




More information about the cfe-dev mailing list