2009-11-22 120 views
0

當我鍵入GCC gprof的-helper.c編譯程序我得到這些錯誤:如何讓這個C程序編譯?

gprof-helper.c: In function `wooinit': 
gprof-helper.c:38: error: `RTLD_NEXT' undeclared (first use in this function) 
gprof-helper.c:38: error: (Each undeclared identifier is reported only once 
gprof-helper.c:38: error: for each function it appears in.) 

這是程序文件:

#define _GNU_SOURCE 
#include <sys/time.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <dlfcn.h> 
#include <pthread.h> 

static void * wrapper_routine(void *); 

/* Original pthread function */ 
static int (*pthread_create_orig)(pthread_t *__restrict, 
            __const pthread_attr_t *__restrict, 
            void *(*)(void *), 
            void *__restrict) = NULL; 

/* Library initialization function */ 
void wooinit(void) __attribute__((constructor)); 

void wooinit(void) 
{ 
    pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create"); 
    fprintf(stderr, "pthreads: using profiling hooks for gprof\n"); 
    if(pthread_create_orig == NULL) 
    { 
     char *error = dlerror(); 
     if(error == NULL) 
     { 
      error = "pthread_create is NULL"; 
     } 
     fprintf(stderr, "%s\n", error); 
     exit(EXIT_FAILURE); 
    } 
} 

/* Our data structure passed to the wrapper */ 
typedef struct wrapper_s 
{ 
    void * (*start_routine)(void *); 
    void * arg; 

    pthread_mutex_t lock; 
    pthread_cond_t wait; 

    struct itimerval itimer; 

} wrapper_t; 

/* The wrapper function in charge for setting the itimer value */ 
static void * wrapper_routine(void * data) 
{ 
    /* Put user data in thread-local variables */ 
    void * (*start_routine)(void *) = ((wrapper_t*)data)->start_routine; 
    void * arg = ((wrapper_t*)data)->arg; 

    /* Set the profile timer value */ 
    setitimer(ITIMER_PROF, &((wrapper_t*)data)->itimer, NULL); 

    /* Tell the calling thread that we don't need its data anymore */ 
    pthread_mutex_lock(&((wrapper_t*)data)->lock); 
    pthread_cond_signal(&((wrapper_t*)data)->wait); 
    pthread_mutex_unlock(&((wrapper_t*)data)->lock); 

    /* Call the real function */ 
    return start_routine(arg); 
} 

/* Our wrapper function for the real pthread_create() */ 
int pthread_create(pthread_t *__restrict thread, 
        __const pthread_attr_t *__restrict attr, 
        void * (*start_routine)(void *), 
        void *__restrict arg) 
{ 
    wrapper_t wrapper_data; 
    int i_return; 

    /* Initialize the wrapper structure */ 
    wrapper_data.start_routine = start_routine; 
    wrapper_data.arg = arg; 
    getitimer(ITIMER_PROF, &wrapper_data.itimer); 
    pthread_cond_init(&wrapper_data.wait, NULL); 
    pthread_mutex_init(&wrapper_data.lock, NULL); 
    pthread_mutex_lock(&wrapper_data.lock); 

    /* The real pthread_create call */ 
    i_return = pthread_create_orig(thread, 
            attr, 
            &wrapper_routine, 
            &wrapper_data); 

    /* If the thread was successfully spawned, wait for the data 
    * to be released */ 
    if(i_return == 0) 
    { 
     pthread_cond_wait(&wrapper_data.wait, &wrapper_data.lock); 
    } 

    pthread_mutex_unlock(&wrapper_data.lock); 
    pthread_mutex_destroy(&wrapper_data.lock); 
    pthread_cond_destroy(&wrapper_data.wait); 

    return i_return; 
} 

如何擺脫這些錯誤的?

+1

這看起來像http://stackoverflow.com/questions/1777397/rtldnext-undeclared – hallski 2009-11-22 01:59:04

+0

同樣的副本,請參閱http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html(更多詳情關於這個問題) – 2009-11-22 02:00:59

+1

我認爲,如果我包括整個程序文件,我會得到更好的答案。 – neuromancer 2009-11-22 02:01:23

回答

2

RTLD_NEXT自古以來就有glibc可供使用。
您是基於Linux(或基於glibc的)系統構建的嗎?聽起來不像。

更新:
RTLD_NEXTglibc擴展。您不能在cygwin上使用它,因爲cygwin!= glibc
據我所知,cygwin也不支持LD_PRELOAD,所以即使您成功構建這個庫,它也不會很有用。

+1

我正在cygwin建設。 – neuromancer 2009-11-22 02:09:26

+0

@Phenom:你應該早些說過; cygwin不支持'RTLD_NEXT'(參見例如2008年10月以來的這個消息http://lists.zerezo.com/cygwin/msg38882.html) – Christoph 2009-11-22 02:34:37