public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
From: Boris Ouretskey <borisusun@gmail.com>
To: libc-help@sourceware.org
Subject: Destruction order of function static members of different translation units
Date: Thu, 9 Dec 2021 15:35:17 +0200	[thread overview]
Message-ID: <CAG4AAQ3KAUb+fuMxyj+L3Obvwv=xxA0QXXDXxw5Nw7HEPBOZ1A@mail.gmail.com> (raw)

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.

             reply	other threads:[~2021-12-09 13:35 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-09 13:35 Boris Ouretskey [this message]
2021-12-14 11:28 ` Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAG4AAQ3KAUb+fuMxyj+L3Obvwv=xxA0QXXDXxw5Nw7HEPBOZ1A@mail.gmail.com' \
    --to=borisusun@gmail.com \
    --cc=libc-help@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).