title: Destructor of static object not (always) called with LD_PRELOAD
body: <p>I want to use the LD_PRELOAD mechanism GNU's dynamic loader to inject code into other binaries. In my code I use a static object to have code executed right at the start and the very end of the augmented program (called Prog later on). Execution order of static initialisers should not concern me as I do not access any data of Prog and I also don't care when exactly my code runs as long as it's "close enough" to the start/end of Prog's "main".</p>
  
  <p>The problem is that for some binaries this approach works fine while for others the destructor of the static object is simply not invoked.</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;
  
  namespace {
  struct Stat {
          Stat()  { std::cerr &lt;&lt; "Ctor" &lt;&lt; std::endl; }
          ~Stat() { std::cerr &lt;&lt; "Dtor" &lt;&lt; std::endl; }
  };
  }
  
  Stat s;
  </code></pre>
  
  <p>Compilation:
  <code>$ g++ -shared -fpic -o ~/preload.so preload.cc</code></p>
  
  <p>Usage:</p>
  
  <pre><code>$ LD_PRELOAD=~/preload.so /bin/true
  Ctor
  Dtor
  </code></pre>
  
  <pre><code>$ LD_PRELOAD=~/preload.so /bin/sleep 1
  Ctor
  </code></pre>
  
  <p>In the first case with <code>true</code> everything works as expected but in the second case (and most/all others) the destructor is never called. I excluded problems with the standard streams beeing destructed "too early" by replacing the string output with <code>sleep</code> … works for <code>true</code>, fails for <code>sleep</code>. <strong>(Edit:</strong> Ignore that last part. I messed up with the compilation and ran the version without <code>sleep</code> yet again. <code>sleep</code> actually works, so @dms is right. It does not explain the doubly printed "Ctor" in gdb, but I don't care too much about that artifact.<strong>)</strong></p>
  
  <p>Weirder still. When I try to run the examples in gdb (with <code>set env LD_PRELOAD ...</code>), "Ctor" is printed twice. If I set a breakpoint at <code>Stat</code> it triggers only after the first time "Ctor" is output. A breakpoint on <code>~Stat</code> does trigger but still no output.</p>
  
  <p>There's a <a href="https://stackoverflow.com/q/22500229/11972761">similar question</a> about static object dtors in DLLs. The answers there are either Windows specific or imply that static dtors are never called for dynamically loaded libraries which obviously is not true in my case.</p>