[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?
More information about the cfe-dev