title: Destructor of a global static variable in a shared library is not called on dlclose
body: <p>In a main program, I <code>dlopen</code> and <code>dlclose</code> (<code>LoadLibrary</code> and <code>FreeLibrary</code> respectively) a shared library. The shared library contains a static variable that is instantiated upon <code>dlopen</code>, and destroyed upon <code>dlclose</code>. This behavior is consistent on MSVC 2008 and 2013, GCC 3.4.6, and  Sunstudio 12.1.
  With GCC 4.9.1 and GCC 5.2.1 however, the destructor was no longer called on <code>dlclose</code>. Instead, it was called before program exit.</p>
  
  <p>The particularity of the static variable's class, is that in the constructor, there is a call to a templated function <em>get</em> (of global scope) that returns a local <strong>static</strong> variable.</p>
  
  <p>I was able to reproduce this behavior with the following one cpp file linked into a shared library:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  template &lt;typename T&gt; // In my actual code, i is of type T, however, this has no effect
  int get()
  {
     static int i = 0;
     return i;
  }
  
  class Dictionary {
  public:
     Dictionary()
     {
        std::cout &lt;&lt; "Calling Constructor" &lt;&lt; std::endl;
        get&lt;int&gt;();
     }
     ~Dictionary(){
        std::cout &lt;&lt; "Calling Destructor" &lt;&lt; std::endl;
     }
  
  private:
     Dictionary(const Dictionary&amp;);
     Dictionary&amp; operator=(const Dictionary&amp;);
  };
  static Dictionary d;
  </code></pre>
  
  <p>I investigated the tweaks that can be made in order to have the destructor called on dlclose, and concluded the following:</p>
  
  <ul>
  <li>If the function <em>get</em> was not templated</li>
  <li>else if the variable i in the function <em>get</em> was not static</li>
  <li>else if the function <em>get</em> is made static</li>
  </ul>
  
  <p>The main program's code is the following:</p>
  
  <pre><code>#include &lt;dlfcn.h&gt;
  #include &lt;cassert&gt;
  #include &lt;string&gt;
  #include &lt;iostream&gt;
  
  void* LoadLib(std::string name)
  {
        void* libInstance;
        name = "lib" + name + ".so";
        libInstance = dlopen(name.c_str(), RTLD_NOW);
        if ( ! libInstance ) std::cout &lt;&lt; "Loading of dictionary library failed. Reason: " &lt;&lt; dlerror() &lt;&lt; std::endl;
        return libInstance;
  }
  
  bool UnloadLib(void* libInstance)
  {
       int ret = dlclose(libInstance);
       if (ret == -1)
       {
          std::cout &lt;&lt; "Unloading of dictionary library failed. Reason: " &lt;&lt; dlerror() &lt;&lt; std::endl;
          return false;
       }
       return true;
  }
  
  int main()
  {
     void* instance = LoadLib("dll");
     assert(instance != 0);
  
     assert(UnloadLib(instance));
     std::cout &lt;&lt; "DLL unloaded" &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>I built the binaries with the following commands:</p>
  
  <pre><code>g++ -m64 -g -std=c++11 -shared -fPIC dll.cpp -o libdll.so
  g++ -m64 -g -std=c++11 -ldl main.cpp -o main.out
  </code></pre>
  
  <p>The output I get when the destructor is called before program exit is the following:</p>
  
  <pre><code>Calling Constructor
  DLL unloaded
  Calling Destructor
  </code></pre>
  
  <p>The output I get when the destructor is called on dlclose is the following:</p>
  
  <pre><code>Calling Constructor
  Calling Destructor
  DLL unloaded
  </code></pre>
  
  <p>Questions:</p>
  
  <ul>
  <li>If the change of behavior between the versions of GCC is not a bug, can you please explain why is the destructor not called on dlclose?</li>
  <li>Can you please explain for each tweak: Why is the destructor called on dlclose in this case?</li>
  </ul>