title: Wrapped function is only called from linked library when linking as -static
body: <p><em>Edit</em>: Made title a bit clearer.</p>
  
  <p>I am trying to wrap glibc's <code>__assert_fail</code> and <code>__assert_perror_fail</code> functions with my own that log the messages using <code>syslog</code>.</p>
  
  <p>I have verified that if I fail an assert my functions get called. The problem lies in libzmq's assertions. libzmq's assertions only invoke my wrapper functions when I build with <code>-static</code>.</p>
  
  <p><strong>NOTES</strong></p>
  
  <ul>
  <li><p>I patched libzmq to call <code>__assert_*</code> instead of <code>fprintf(stderr, ...)</code>, and I have verified that it correctly calls <code>__assert_*</code>.</p></li>
  <li><p>I also patched libzmq to randomly have assertion failures from within the zmq_assert macros so that I can easily reproduce. If the patch is wanted, I will put it up.</p></li>
  </ul>
  
  <p>Here is some test code</p>
  
  <pre class="lang-c++ prettyprint-override"><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;assert.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;string.h&gt;
  #include &lt;zmq.h&gt;
  
  extern "C" void
  __wrap___assert_perror_fail(int __errnum, const char *__file,
                              unsigned int __line, const char *__function)
  {
          fprintf(stderr, "TESTING123:: %s:%u %s: Unexpected error: %s.\n",
                  __file, __line, __function, strerror(__errnum));
          abort();
  }
  
  extern "C" void
  __wrap___assert_fail(const char *__assertion, const char *__file,
                       unsigned int __line, const char *__function)
  {
          fprintf(stderr, "TESTING123:: %s:%u %s: Assertion '%s' failed.\n",
                  __file, __line, __function, __assertion);
          abort();
  }
  
  int main()
  {
  #ifdef DO_ASSERT
          assert(1 == 0);
  #endif
          void *ctx = zmq_init(0);
          void *req = zmq_socket(ctx, ZMQ_REQ);
          void *rep = zmq_socket(ctx, ZMQ_REQ);
          zmq_bind(rep, "inproc://inproc-1");
          zmq_connect(req, "inproc://inproc-1");
          unsigned long long c = 0;
          while (1) {
                  zmq_msg_t msg;
  
                  zmq_msg_init_size(&amp;msg, 1024);
                  zmq_send(req, &amp;msg, 0);
                  zmq_msg_close(&amp;msg);
  
                  zmq_msg_init(&amp;msg);
                  zmq_recv(rep, &amp;msg, 0);
                  zmq_send(rep, &amp;msg, 0);
                  zmq_msg_close(&amp;msg);
  
                  zmq_msg_init(&amp;msg);
                  zmq_recv(req, &amp;msg, 0);
                  zmq_msg_close(&amp;msg);
  
                  ++c;
                  if (c % 1000000 == 0) {
                          fprintf(stderr, "processed %llu messages\n", c);
                  }
          }
          return 0;
  }
  </code></pre>
  
  <p>Which I build 4 ways with/without DO_ASSERT, dynamic/static</p>
  
  <pre class="lang-sh prettyprint-override"><code>$ g++ -DDO_ASSERT -o t-me-dyn t.cc -Wl,-wrap,__assert_fail -Wl,-wrap,__asser_perror_fail -lzmq -lpthread -luuid -lrt 
  $ g++ -static -DDO_ASSERT -o t-me-sta t.cc -Wl,-wrap,__assert_fail -Wl,-wrap,__asser_perror_fail -lzmq -lpthread -luuid -lrt 
  $ g++ -o t-zmq-dyn t.cc -Wl,-wrap,__assert_fail -Wl,-wrap,__asser_perror_fail -lzmq -lpthread -luuid -lrt 
  $ g++ -static -o t-zmq-sta t.cc -Wl,-wrap,__assert_fail -Wl,-wrap,__asser_perror_fail -lzmq -lpthread -luuid -lrt 
  /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../lib/libzmq.a(libzmq_la-ip.o): In function 'zmq::resolve_ip_interface(sockaddr_storage*, unsigned int*, char const*)':
  (.text+0x49b): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
  </code></pre>
  
  <p>And I get the following when running them</p>
  
  <pre class="lang-sh prettyprint-override"><code>$ for bin in t-{me,zmq}-{dyn,sta}; do echo ==== $bin ====; ./$bin; done
  ==== t-me-dyn ====
  TESTING123:: t.cc:29 int main(): Assertion '1 == 0' failed.
  Aborted
  ==== t-me-sta ====
  TESTING123:: t.cc:29 int main(): Assertion '1 == 0' failed.
  Aborted
  ==== t-zmq-dyn ====
  t-zmq-dyn: lb.cpp:142: int zmq::lb_t::send(zmq_msg_t*, int): Assertion 'rc == 0' failed.
  Aborted
  ==== t-zmq-sta ====
  TESTING123:: lb.cpp:142 int zmq::lb_t::send(zmq_msg_t*, int): Assertion 'rc == 0' failed.
  Aborted
  </code></pre>
  
  <p>So what am I doing wrong? According to <code>man ld</code> </p>
  
  <blockquote>
    <p>If you link other code with this file using --wrap malloc, then all calls to "malloc" will call the function "__wrap_malloc" instead.</p>
  </blockquote>
  
  <p>which is not what I am seeing.</p>