This is the mail archive of the
glibc-linux@ricardo.ecn.wfu.edu
mailing list for the glibc project.
Re: Intercepting calls to pthread_create (or any pthreads function)
- To: glibc-linux at ricardo dot ecn dot wfu dot edu
- Subject: Re: Intercepting calls to pthread_create (or any pthreads function)
- From: "Arthur H. Gold" <agold at bga dot com>
- Date: Tue, 06 Mar 2001 17:40:10 -0600
- CC: "Philip J. Mucci" <mucci at cs dot utk dot edu>
- Organization: UTCS OOPS Group
- References: <3AA469E3.9050905@cs.utk.edu>
- Reply-To: glibc-linux at ricardo dot ecn dot wfu dot edu
"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.