public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
* Destruction order of function static members of different translation units
@ 2021-12-09 13:35 Boris Ouretskey
  2021-12-14 11:28 ` Florian Weimer
  0 siblings, 1 reply; 2+ messages in thread
From: Boris Ouretskey @ 2021-12-09 13:35 UTC (permalink / raw)
  To: libc-help

Hi,

I have seen some information on the mailing lists and forums but nothing
really focused. Not sure also if the question is for the libc community or
gcc .

The situation we are dealing with is the "destruction fiasco". Because of
heavily templated code and many SO(DLL) translation units, which are using
common template headers, there are some static storage interdependencies
between functions' static members of different SO. For example:-
----
common_header,h
----
template
struct A<T>
{
void do {};
 static A* Instance()
{
   static A* m_instance;
  ... // create m_instance if null
  return m_instance;
}
}
----
translation_unit1.cpp (tu1) --> compiled into tu1.so
----
#include "common_header,h"
foo()
{
   A<1>::Instance()->do();
   A<2>::Instance()->do();
}

----
translation_unit2.cpp (tu2) --> compiled into a.out executable and links
tu1.so
-----
#include "common_header,h"
bar()
{
   A<1>::Instance()->do();
   A<2>::Instance()->do();
}

What happens in our code is that A<1> ::m_instance is defined in tu1, and
A<2> ::m_instance is defined in tu2.

 Eventually, the program crashes on exit, because the code in the main
module is trying to destruct a static member (say A<2> ::m_instance) which
is using an already destructed global member of tu1  which was already
destroyed before (and unloaded probably?).

I found some answers on the internet telling that destruction order between
different TU is undefined in general. What is confusing me is that in our
case only one object destruction is out of order so probably gcc/libc does
some effort to keep it in order. Only one objects' destruction is postponed
for some reason till the end instead of being dealt with in a "natural"
reverse creation order. and this is the exact object which causes the
trouble.

The questions will be:-
- Is gcc/libc trying their best to keep the creation and destruction order
even between static objects defined in different translation units or none
effort is taken and only order in single TU is preserved?

- If the answer of the previous question is yes then what can cause
changing the order of destruction? So maybe we can dapat our code to not
crash on exit.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Destruction order of function static members of different translation units
  2021-12-09 13:35 Destruction order of function static members of different translation units Boris Ouretskey
@ 2021-12-14 11:28 ` Florian Weimer
  0 siblings, 0 replies; 2+ messages in thread
From: Florian Weimer @ 2021-12-14 11:28 UTC (permalink / raw)
  To: Boris Ouretskey via Libc-help

* Boris Ouretskey via Libc-help:

> I have seen some information on the mailing lists and forums but nothing
> really focused. Not sure also if the question is for the libc community or
> gcc .
>
> The situation we are dealing with is the "destruction fiasco". Because of
> heavily templated code and many SO(DLL) translation units, which are using
> common template headers, there are some static storage interdependencies
> between functions' static members of different SO. For example:-

Current glibc behavior is rather complex.  You can try linking with
-Wl,-z,now (or run with LD_BIND_NOW=1).  This will eliminate relocation
dependencies recorded late at run time and should make the order between
construction and destruction more consistent.  However, the objects are
still dependency-sorted during process termination, and if the sort
picks a different resolution, you might still get different destruction
order.

Would you be able to test a patch that always uses reserve order if
possible?  (There will still be exceptions because dlclose of unrelated
objects can still result in different orders.)

Thanks,
Florian


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-12-14 11:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-09 13:35 Destruction order of function static members of different translation units Boris Ouretskey
2021-12-14 11:28 ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).