title: LD_PRELOAD only working for malloc, not free
body: <p>I'm trying to interpose malloc/free/calloc/realloc etc with some interposers via LD_PRELOAD. In my small test, only <code>malloc</code> seems to be interposed, even though <code>free</code> is detected (see output).</p>
  
  <p>I'd expect the output to contain a line "NANO: free(x)" - but this line is missing.</p>
  
  <p>Given</p>
  
  <pre><code>// compile with: gcc test.cc
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  int main(int argc, char* argv[]) {
  
      void* p = malloc(123);
      printf("HOST p=%p\n", p);
      free(p);
  }
  </code></pre>
  
  <p>And</p>
  
  <pre><code>// compile with:  g++ -O2 -Wall -fPIC -ldl -o libnano.so -shared main.cc
  #include &lt;stdio.h&gt;
  #include &lt;dlfcn.h&gt;
  
  typedef void *(*MallocFunc)(size_t size);
  typedef void (*FreeFunc)(void*);
  
  // Original functions
  static MallocFunc real_malloc = NULL;
  static FreeFunc real_free = NULL;
  
  static void __nano_init(void) {
      // Override original functions
      real_malloc = (MallocFunc)dlsym(RTLD_NEXT, "malloc");
      if (NULL == real_malloc) {
          fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
      } else {
          fprintf(stderr, "NANO: malloc() replaced @%p\n", real_malloc);
      }
  
      real_free = (FreeFunc)dlsym(RTLD_NEXT, "free");
      if (NULL == real_free) {
         fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
      } else {
          fprintf(stderr, "NANO: free() replaced @%p\n", real_free);
      }
  }
  
  // replacement functions
  void *malloc(size_t size) {
      if(real_malloc==NULL) __nano_init();
  
      void *p = NULL;
      fprintf(stderr, "NANO: malloc(%lu) = ", size);
      p = real_malloc(size);
      fprintf(stderr, "%p\n", p);
  
      return p;
  }
  
  void free(void* ptr) {
      if(real_free==NULL) __nano_init();
  
      fprintf(stderr, "NANO: free(%p)\n", ptr);
      real_free(ptr);
  
      return;
  }
  </code></pre>
  
  <p>The actual output is:</p>
  
  <pre><code>% ./a.out
  NANO: malloc() replaced @0x3b36274dc0
  NANO: free() replaced @0x3b36272870
  NANO: malloc(123) = 0x601010
  HOST p=0x601010
  </code></pre>