title: -finstrument-functions doesn't work with dynamically loaded g++ shared objects (.so)
body: <p>I am testing -finstrument-functions with g++ shared object (.so) files on Ubuntu these days. I found a strange behavior that -finstrument-functions seems to work only if the library is statically linked. If I link to the library with dlopen/dlsym etc., the functionality of the code still works, but it won't call the __cyg_profile* functions.</p>
  
  <p>Here are some codes to quickly reproduce the problem:</p>
  
  <p>MyLib.h</p>
  
  <pre><code>#ifndef __MYLIB_H__
  #define __MYLIB_H__
  class MyLib
  {
  public:
      void sayHello();
  };
  #endif
  </code></pre>
  
  <p>MyLib.cpp</p>
  
  <pre><code>#include "MyLib.h"
  #include &lt;iostream&gt;
  using namespace std;
  
  void MyLib::sayHello()
  {
      cout&lt;&lt;"Hello"&lt;&lt;endl;
  }
  </code></pre>
  
  <p>MyLibStub.cpp (C interface to the .so)</p>
  
  <pre><code>#include "MyLib.h"
  
  extern "C" void LoadMyLib ()
  {
      MyLib().sayHello();
  }
  </code></pre>
  
  <p>Trace.cpp</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #ifdef __cplusplus
  extern "C"
  {
      void __cyg_profile_func_enter(void *this_fn, void *call_site)
          __attribute__((no_instrument_function));
      void __cyg_profile_func_exit(void *this_fn, void *call_site)
          __attribute__((no_instrument_function));
  }
  #endif
  
  void __cyg_profile_func_enter(void* this_fn, void* call_site)
  {
      printf("entering %p\n", (int*)this_fn);
  }
  
  void __cyg_profile_func_exit(void* this_fn, void* call_site)
  {
      printf("exiting %p\n", (int*)this_fn);
  }
  </code></pre>
  
  <p>MainStatic.cpp</p>
  
  <pre><code>#include &lt;iostream&gt;
  using namespace std;
  
  extern "C" void LoadMyLib ();
  
  int main()
  {
      LoadMyLib();
      return 0;
  }
  </code></pre>
  
  <p>MainDynamic.cpp</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;dlfcn.h&gt;
  
  const char* pszLibName  = "libMyLib.so.0.0";
  const char* pszFuncName  = "LoadMyLib";
  
  int main()
  {
      void* pLibHandle = dlopen(pszLibName, RTLD_NOW);
      if(!pLibHandle) {
          return 1;
      }
      void (*pFuncLoad)() = 0;
      //Resolve the function in MyLibStub.cpp
      pFuncLoad = (void (*)())dlsym(pLibHandle, pszFuncName);
      if(!pFuncLoad) {
          return 1;
      }
      pFuncLoad();
      dlclose(pLibHandle);
      return 0;
  }
  </code></pre>
  
  <p>and compile with the following commands (under Ubuntu 11.10):</p>
  
  <blockquote>
  <pre><code>g++ -g -finstrument-functions -Wall -Wl,-soname,libMyLib.so.0 -shared -fPIC -rdynamic MyLib.cpp MyLibStub.cpp Trace.cpp -o libMyLib.so.0.0  
  ln -s libMyLib.so.0.0 libMyLib.so.0  
  ln -s libMyLib.so.0.0 libMyLib.so  
  g++ MainStatic.cpp -g -Wall -lMyLib -L./ -o MainStatic   
  g++ MainDynamic.cpp -g -Wall -ldl -o MainDynamic
  </code></pre>
  </blockquote>
  
  <p>when called with <code>./MainStatic</code></p>
  
  <p>it gives something like:</p>
  
  <blockquote>
  <pre><code>entering 0xb777693f
  entering 0xb777689b
  exiting 0xb777689b
  exiting 0xb777693f
  entering 0xb7776998
  entering 0xb777680c
  Hello
  exiting 0xb777680c
  exiting 0xb7776998
  </code></pre>
  </blockquote>
  
  <p>however, when called with <code>./MainDynamic</code></p>
  
  <p>it only gives a "Hello".</p>
  
  <blockquote>
  <pre><code>Hello
  </code></pre>
  </blockquote>
  
  <p>Does anybody here know why there is such difference between statically and dynamically linked libraries? Is there any solution to make it work even when dynamically loaded? Thanks in advance.</p>