p_read_create的LD_PRELOAD问题

时间:2012-06-05 15:13:15

标签: c linux gcc pthreads ld-preload

我只是在玩LD_PRELOAD的概念。看起来它工作正常,直到我开始在我的代码中使用pthread库函数。当我这样做时,我得到分段错误。 LD_PRELOAD是否对pthread库有某种厌恶或什么?

这里显示的是程序和LD_PRELOADed .so代码。

程序代码

// main.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>

#define USE_PTHREADS

#define NUM_THREADS     8

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

int sum;
float total = 1;
extern int __did_libc_start_main;

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   pthread_mutex_lock( &m );
   sum++;
   total *= total + tid * 0.097891313423578;
   printf( "p%d, tid%d, total = %g, start = %d!\n", getpid(), tid, 
      total, 0 );
   pthread_mutex_unlock( &m );
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   char * p;
   char * m;

   fork();

   p = (char*)mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 
     -1, 0);
   p[0] = 78;
   printf( "p = %p, p[0] = %d, pid = %d!\n", p, p[0], getpid() );
   m = (char*)malloc( 80 );
   printf( "m = %p!\n", m );
#ifdef USE_PTHREADS // If we disable this part of code, LD_PRELOAD works fine
   for(t=0; t<NUM_THREADS; t++)
   {
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }
   for(t=0; t<NUM_THREADS; t++)
    pthread_join(threads[t], NULL);

   printf( "\n\nTotal = %g\n\n", total );

   /* Last thing that main() should do */
   pthread_exit(NULL);
#endif
   printf( "\n\n%d: Done without major problems\n\n", getpid() );
   return 0;
}

LD_PRELOADed .so code

// prelib.c
#define _GNU_SOURCE

//#include <sys/syscall.h>
//#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <dlfcn.h>

typedef pid_t (*getpidType)(void);
typedef void* (*mmapType)(void *addr, size_t len, int prot, int flags,
       int fildes, off_t off);

pid_t getpid(void)
{
    static int first_time = 1;
    static getpidType f;

    printf("Hello, getpid!\n");

    if ( first_time )
    {
        f = (getpidType)dlsym(RTLD_NEXT, "getpid");
        first_time = 0;
    }

    return f();
}
void *mmap(void *addr, size_t len, int prot, int flags,
       int fildes, off_t off)
{
    static int first_time = 1;
    static mmapType f;

    printf( "My mmap!\n" );
    if ( first_time )
    {
        f = (mmapType)dlsym(RTLD_NEXT, "mmap" );
        first_time = 0;
    }

    return f( addr, len, prot, flags, fildes, off );
}

当定义了USE_PTHREADS时,我得到这样的错误。

My mmap!
<< mutex_trylock >>
<< mutex_unlock >>
Hello, getpid!
p = 0x2ab9bc969000, p[0] = 78, pid = 9763!
m = 0x179d4010!
In main: creating thread 0
My mmap!
<< mutex_trylock >>
My mmap!
<< mutex_trylock >>
<< mutex_unlock >>
Hello, getpid!
p = 0x2ab9bc969000, p[0] = 78, pid = 9762!
m = 0x179d4010!
In main: creating thread 0
My mmap!
<< mutex_trylock >>
Segmentation fault

2 个答案:

答案 0 :(得分:0)

我怀疑这是你唯一的问题,但是你的&#34; first_time&#34; hack不同步,因此不是线程安全的。您应该使用pthread_once函数来实现此目的,或使用互斥锁或信号量滚动您自己的版本。

答案 1 :(得分:0)

我唯一能想到的是:

printf(“p%d,tid%d,total =%g,start =%d!\ n”,getpid(),tid,       总计,0);

应该是tid% ld

也许你在64位上运行而且longs不是int size。那么当它打印浮动时,它会看到垃圾并且你正在崩溃printf。