This is the mail archive of the glibc-linux@ricardo.ecn.wfu.edu 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]

Re: Intercepting calls to pthread_create (or any pthreads function)


"Philip J. Mucci" wrote:
> 
> Hi all,
> 
> I'm trying to intercept calls to pthread_create so as I can call a
> monitor function in the context of the newly created thread. I thought I
> might be able to do this with LD_PRELOAD and some dlopen() tricks, but
> unfortunately, I keep getting segfaults. I'm guessing that by dlopen'ing
> the new pthreads library, I'm initializing an entirely new copy of the
> library, which is not what I want.
Not exactly; but it's still not the optimal solution.
Since `libpthread.so' is already linked into your program,
instead of doing a dlopen/dlsym just do a `dlsym( RTLD_NEXT,
"pthread_create" )' to obtain the pointer to the `real'
pthread_create.

There's also the issue of how you compile/link the .so you
plan to use via LD_PRELOAD. For example, you should not have
to `#define _REENTRANT' in your code at all -- you should
link in linuxthreads by using the `-pthread' option, as it
makes sure that `_REENTRANT' is defined, as well as making
sure that the library shows up in the link order at the
right place.

[cc:-ed to OP]

HTH,
--ag

[BTW -- I've done extensive LD_PRELOAD stuff; feel free to
contact me directly --ag]
> 
> So my question is, how can I intercept a call and then call the real
> version? Is it possible? The real reason I need to do this is to enable
> a profiling timer in the child thread.
> 
> Thanks,
> 
> #define _REENTRANT
> #include <pthread.h>
> #include <stdio.h>
> #include <dlfcn.h>
> 
> typedef struct {
>      void *arg;
>      void *(*fn)(void *);
> } real_args;
> 
> void *create_head(void *arg)
> {
>    real_args *a = arg;
> 
>    fprintf(stderr,"PID %d TID %d\n",
>           getpid(),(int)pthread_self());
>    return(a->fn(a->arg));
> }
> 
> int pthread_create(pthread_t  *thread,
>                    __const pthread_attr_t *attr,
>                    void * (*start_routine)(void *), void * arg)
> {
>    real_args args;
>    static void *handle = NULL;
>    static int (*real_pthread_create)(pthread_t  *,
>                              __const pthread_attr_t *,
>                           void * (*)(void *), void *) = NULL;
> 
>    args.arg = arg;
>    args.fn = start_routine;
> 
>    if (handle == NULL)
>      {
>        handle = dlopen("/usr/lib/libpthread.so",RTLD_LAZY);
>        if (handle == NULL)
>         {
>           fprintf(stderr,"dlopen(%s) failed\n","/usr/lib/libpthread.so");
>           exit(1);
>         }
>        real_pthread_create = dlsym(handle,"pthread_create");
>        if (handle == NULL)
>         {
>           fprintf(stderr,"dlsym(%s) failed\n","pthread_create");
>           exit(1);
>         }
>      }
>    return(real_pthread_create(thread,attr,create_head,&args));
> }

-- 
Artie Gold, Austin, TX  (finger the cs.utexas.edu account
for more info)
mailto:agold@bga.com or mailto:agold@cs.utexas.edu
--
Verbing weirds language.


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