This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Wrapping versioned glibc symbol


On Fri, Apr 24, 2009 at 14:05:43 +0400, Tomash Brechko wrote:
> So, is there a canonical way to wrap versioned functions?  Perhaps I
> approach the problem from the wrong side...

I'm still curious learning how to solve the problem "statically"
(i.e. at compile time), if possible at all.  However my colleague
reminded me that I can just use dlsym().  First I tried

  __pthread_cond_signal = dlsym(RTLD_NEXT, "pthread_cond_signal");

This seemed to work, but in gdb I noticed that __pthread_cond_signal
is bound to pthread_cond_signal@GLIBC_2.0, not
pthread_cond_signal@@GLIBC_2.3.2 !  For glibc 2.8 the program below
outputs

  $ ./test
  pthread_cond_signal:
  ./libc_bug(pthread_cond_signal+0x0)[0x8048524]
  RTLD_DEFAULT:
  ./libc_bug(pthread_cond_signal+0x0)[0x8048524]
  RTLD_NEXT:
  /lib/libpthread.so.0(pthread_cond_signal+0x0)[0xd19950]
  dlopen:
  /lib/libpthread.so.0(pthread_cond_signal+0x0)[0xd196a0]

  $ nm /lib/libpthread.so.0 | grep '\bpthread_cond_signal\b'
  00d196a0 T pthread_cond_signal@@GLIBC_2.3.2
  00d19950 T pthread_cond_signal@GLIBC_2.0

As you can see, RTLD_DEFAULT binds to my own definition, but RTLD_NEXT
binds to @GLIBC_2.0, skipping @@GLIBC_2.3.2.  I think this contradicts
man dlopen, that says that RTLD_NEXT "allows one to provide a wrapper
around a function in another shared library".  The only working
solution left is to explicitly dlopen("/lib/libpthread.so.0", ...).


  /*
    gcc -pthread test.c -o test -ldl
    ./test
    nm /lib/libpthread.so.0 | grep '\bpthread_cond_signal\b'
  */

  #define _GNU_SOURCE
  #include <dlfcn.h>
  #include <pthread.h>
  #include <stdio.h>

  int
  pthread_cond_signal(pthread_cond_t *cond)
  {
    return 0;
  }

  int
  main()
  {
    void *libpthread;
    void *addr;
  
    fputs("pthread_cond_signal:\n", stdout);
    addr = pthread_cond_signal;
    backtrace_symbols_fd(&addr, 1, 1);
  
    fputs("RTLD_DEFAULT:\n", stdout);
    addr = dlsym(RTLD_DEFAULT, "pthread_cond_signal");
    backtrace_symbols_fd(&addr, 1, 1);
  
    fputs("RTLD_NEXT:\n", stdout);
    addr = dlsym(RTLD_NEXT, "pthread_cond_signal");
    backtrace_symbols_fd(&addr, 1, 1);
  
    fputs("dlopen:\n", stdout);
    libpthread = dlopen("/lib/libpthread.so.0", RTLD_LAZY);
    addr = dlsym(libpthread, "pthread_cond_signal");
    backtrace_symbols_fd(&addr, 1, 1);
  
    return 0;
  }



-- 
   Tomash Brechko


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]