title: Static objects destructed BEFORE dlclose()
body: <p>I'm working on a cross-platform project which consists on several libraries, dynamically loading and unloading one another depending on run-time conditions. Currently I observe a crash which seems to be caused by the fact that static objects in one of the shared libraries are destroyed before the shared library is unloaded with dlclose(). This seems pretty strange and more like a bug to me.</p>
  
  <p>To investigate the problem I've created a simple project, which consists of three source files: main.cpp, lib1.cpp and lib2.cpp (for executable and two libraries respectively). The main executable dynamically loads lib1, and lib1 in turn dynamically loads lib2.</p>
  
  <p>main.cpp:</p>
  
  <pre><code>Logger mainGlobal("mainGlobal");
  
  int main(int argc, char * argv[])
  {
      Logger mainFunction("mainFunction");
      try
      {
          Logger mainTry("mainTry");
          libutil::AutoLib lib("lib1");
          lib.call("loadLib2");
      }
      catch (std::exception &amp; e)
      {
          std::cerr &lt;&lt; "Fatal: " &lt;&lt; e.what() &lt;&lt; std::endl;
      }
      std::cout &lt;&lt; "Exiting main" &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>lib1.cpp:</p>
  
  <pre><code>Logger lib1Global("lib1Global");
  
  std::auto_ptr&lt;libutil::AutoLib&gt; lib2;
  
  DLL_EXPORT void loadLib2()
  {
      std::cout &lt;&lt; "loadLib2" &lt;&lt; std::endl;
      lib2.reset(new libutil::AutoLib("lib2"));
  }
  </code></pre>
  
  <p>lib2.cpp:</p>
  
  <pre><code>Logger lib2Global("lib2Global");
  </code></pre>
  
  <p><code>Logger</code> is a simple struct which just logs in its constructor and destructor. <code>libutil::AutoLib</code> is a shared library loader which calls <code>dlopen(path, RTLD_LAZY)</code> in its ctor, and calls <code>dlclose()</code> in its dtor, and allows to call functions exported from a shared library. The code for those classes is trivial, but I can post it here as well if needed.</p>
  
  <p>Long story short, if I call main executable, I see the following log:</p>
  
  <pre><code>mainGlobal ctor
  mainFunction ctor
  mainTry ctor
  Loading library lib1.so
  lib1Global ctor
  dlopen(lib1.so) returned 0x14cd050
  Library lib1.so loaded with handle 0x14cd050
  Calling loadLib2 in library 0x14cd050
  loadLib2
  Loading library lib2.so
  lib2Global ctor
  dlopen(lib2.so) returned 0x14cd710
  Library lib2.so loaded with handle 0x14cd710
  Unloading library 0x14cd050
  Calling dlclose(0x14cd050)
  Library unloaded 0x14cd050
  mainTry dtor
  Exiting main
  mainFunction dtor
  lib2Global dtor
  Unloading library 0x14cd710
  Calling dlclose(0x14cd710)
  Library unloaded 0x14cd710
  lib1Global dtor
  mainGlobal dtor
  </code></pre>
  
  <p>Please note the <code>lib2Global dtor</code> line going before the <code>Calling dlclose(0x14cd710)</code> line.</p>
  
  <p>So the question is, is it a bug or correct behavior?</p>
  
  <p>There are questions here in SO about static objects not being destroyed after <code>dlclose()</code>, but I did not find any questions about somewhat the opposite situation.</p>
  
  <p>I'm using GCC 5.4.0-6ubuntu1~16.04.10.</p>