<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 18, 2016 at 2:08 PM, Richard Smith via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Mon, Jul 18, 2016 at 1:39 PM, Bruno Cardoso Lopes via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
C++ static destructors can be problematic in multi-threaded<br>
environment. Some of the issues users often complain about include:<br>
1. Teardown ordering: crashes when one thread is exiting the process<br>
and calling destructors while another thread is still running and<br>
accessing the destructing variables<br>
2. Shared code that is compiled both as an application and as a<br>
library. When library mode is chosen, goto (1).<br>
3. Some projects currently override __cxa_atexit to avoid the behavior<br>
in question.<br>
<br>
To get around that, I propose we add a compiler option (e.g.<br>
-fno-cxx-static-destructors) to allow clang to suppress destructor<br>
registration (currently done via __cxa_atexit, atexit):<br>
<a href="https://reviews.llvm.org/D22474" rel="noreferrer" target="_blank">https://reviews.llvm.org/D22474</a><br>
<br>
I'm opening this discussion here on cfe-dev to get some feedback on the matter<br>
<br>
One can argue that dealing with C++ static destructors in<br>
multi-threaded environment is solely the responsibility of the<br>
developer, however since (AFAIK) we don't have any standard guaranteed<br>
semantic for "global destruction vs. threads", it seems fair to me<br>
that we could give developers some option.</blockquote><div><br></div></span><div>They already have options. They can use std::quick_exit, which was added specifically to address this problem, if they don't want destructors to be run at all. There are standard techniques to avoid destructors being run for specific objects:</div><div><br></div><div>  template<typename T> union not_destroyed {</div><div>    T value;</div><div>    template<typename ...U> constexpr not_destroyed(U &&...u) : value(std::forward<U>(u)...) {}</div><div>    ~not_destroyed() {} </div><div>  };</div><div>  not_destroyed<std::string> my_str("foo"); // technically has object lifetime issues</div><div><br></div><div>  ... or ...</div><div><br></div><div>  std::string &&s = *new std::string("foo");</div><div><br></div><div>Are these options not good enough? Is per-TU control (with no source changes) a goal here, or is it more of an incidental property of the solution? It seems to me that we should prefer to either push people towards the standard std::quick_exit solution or propose an alternative standard mechanism rather than invent our own proprietary way to work around this problem.</div></div></div></div></blockquote><div><br></div><div><br></div><div>This doesn't sound like Bruno's use case, but at least for games, we know they never exit (or when they do they don't care about destructors). Avoiding emitting destructors can give a size benefit in such scenarios. Also, it can theoretically (I have not measured this, but it doesn't sound far-fetched) eliminate some references to global variables which in an LTO context can allow for more aggressive optimizations.</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div></div>