title: Overriding 'malloc' using the LD_PRELOAD mechanism
body: <p>I'm trying to write a simple shared library that would log malloc calls to stderr (a sort of 'mtrace' if you will).</p>
  
  <p>However, this is not working.
  Here's what I do:</p>
  
  <pre><code>/* mtrace.c */
  #include &lt;dlfcn.h&gt;
  #include &lt;stdio.h&gt;
  
  static void* (*real_malloc)(size_t);
  
  void *malloc(size_t size)
  {
      void *p = NULL;
      fprintf(stderr, "malloc(%d) = ", size);
      p = real_malloc(size);
      fprintf(stderr, "%p\n", p);
      return p;
  }
  
  static void __mtrace_init(void) __attribute__((constructor));
  static void __mtrace_init(void)
  {
      void *handle = NULL;
      handle = dlopen("libc.so.6", RTLD_LAZY);
      if (NULL == handle) {
          fprintf(stderr, "Error in `dlopen`: %s\n", dlerror());
          return;
      }
      real_malloc = dlsym(handle, "malloc");
      if (NULL == real_malloc) {
          fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
          return;
      }
  }
  </code></pre>
  
  <p>I compile this with:</p>
  
  <pre><code>gcc -shared -fPIC -o mtrace.so mtrace.c
  </code></pre>
  
  <p>And then when I try to execute <code>ls</code>:</p>
  
  <pre><code>$ LD_PRELOAD=./mtrace.so ls
  malloc(352) = Segmentation fault
  </code></pre>
  
  <p>Now, I suspect that dlopen needs malloc, and as I am redefining it within the shared library, it uses that version with the still unassigned <code>real_malloc</code>.</p>
  
  <p>The question is...how do I make it work?</p>
  
  <p>P.S. sorry for the paucity in tags, I couldn't find appropriate tags, and I still don't have enough reputation to create new ones.</p>