Ben Craig via llvm-dev
2018-Jul-17 17:52 UTC
[llvm-dev] [cfe-dev] [RFC] Suppress C++ static destructor registration
My interpretation of the C++ standard is that today's freestanding C++ implementations (between C++98 and C++17) are already allowed to skip global destructors. http://eel.is/c++draft/basic.start#main-1 So re-label the toolchain from hosted to freestanding, change nothing else except start-up and termination, and you still have a compliant (but unorthodox) implementation. I've got a paper that discusses some of this (along with a lot of other embedded-hostile features) here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1105r0.html> -----Original Message----- > From: cfe-dev <cfe-dev-bounces at lists.llvm.org> On Behalf Of David Chisnall > via cfe-dev > Sent: Tuesday, July 17, 2018 2:15 AM > To: JF Bastien <jfbastien at apple.com> > Cc: cfe-dev at lists.llvm.org; Bruno Cardoso Lopes <blopes at apple.com> > Subject: Re: [cfe-dev] [RFC] Suppress C++ static destructor registration > > 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 > > _______________________________________________ > cfe-dev mailing list > cfe-dev at lists.llvm.org > https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.llvm.org_cgi- > 2Dbin_mailman_listinfo_cfe- > 2Ddev&d=DwIGaQ&c=I_0YwoKy7z5LMTVdyO6YCiE2uzI1jjZZuIPelcSjixA&r=y8 > mub81SfUi-UCZRX0Vl1g&m=HxCl5f-t- > UkQZp2CkeD_xRdlXcwFkEmw0QbDAVUlQ64&s=M4RhJONiFXWSmezJsv1xLQ > oNt--UJoWYQ2vVyn7s730&e=
Eric Fiselier via llvm-dev
2018-Jul-17 19:06 UTC
[llvm-dev] [cfe-dev] [RFC] Suppress C++ static destructor registration
+1 for a [[no_destroy]] attribute. There are a couple of places libc++ could benefit from having it, but we couldn't turn of static destructors in general. On Tue, Jul 17, 2018 at 11:54 AM Ben Craig via llvm-dev < llvm-dev at lists.llvm.org> wrote:> My interpretation of the C++ standard is that today's freestanding C++ > implementations (between C++98 and C++17) are already allowed to skip > global destructors. http://eel.is/c++draft/basic.start#main-1 > > So re-label the toolchain from hosted to freestanding, change nothing else > except start-up and termination, and you still have a compliant (but > unorthodox) implementation. > > I've got a paper that discusses some of this (along with a lot of other > embedded-hostile features) here: > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1105r0.html > > > > -----Original Message----- > > From: cfe-dev <cfe-dev-bounces at lists.llvm.org> On Behalf Of David > Chisnall > > via cfe-dev > > Sent: Tuesday, July 17, 2018 2:15 AM > > To: JF Bastien <jfbastien at apple.com> > > Cc: cfe-dev at lists.llvm.org; Bruno Cardoso Lopes <blopes at apple.com> > > Subject: Re: [cfe-dev] [RFC] Suppress C++ static destructor registration > > > > 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 > > > > _______________________________________________ > > cfe-dev mailing list > > cfe-dev at lists.llvm.org > > https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.llvm.org_cgi- > > 2Dbin_mailman_listinfo_cfe- > > 2Ddev&d=DwIGaQ&c=I_0YwoKy7z5LMTVdyO6YCiE2uzI1jjZZuIPelcSjixA&r=y8 > > mub81SfUi-UCZRX0Vl1g&m=HxCl5f-t- > > UkQZp2CkeD_xRdlXcwFkEmw0QbDAVUlQ64&s=M4RhJONiFXWSmezJsv1xLQ > > oNt--UJoWYQ2vVyn7s730&e> _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180717/d17cfa01/attachment.html>