2009-11-22 104 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