Как скомпилировать эту программу на C?

Когда я набираю gcc gprof-helper.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;
}

Как мне избавиться от этих ошибок?


person neuromancer    schedule 22.11.2009    source источник
comment
Это похоже на дубликат stackoverflow.com/questions/1777397/rtldnext-undeclared   -  person hallski    schedule 22.11.2009
comment
Также см. opengroup.org/onlinepubs/009695399/functions/dlsym.html (подробнее о проблеме)   -  person Michael Todd    schedule 22.11.2009
comment
Я подумал, что если я включу весь программный файл, я получу более точные ответы.   -  person neuromancer    schedule 22.11.2009
comment
Так почему бы вам просто не добавить дополнительную информацию о программном файле к исходному вопросу, который вы задали час назад? Зачем начинать совершенно новый вопрос?   -  person Jarret Hardie    schedule 22.11.2009
comment
@Phenom: публикация всего источника будет включать много постороннего кода. Лучше опубликовать минимальный тестовый пример: ровно столько кода, чтобы продемонстрировать проблему, и не более того.   -  person outis    schedule 22.11.2009
comment
Я подумал, может, кто-нибудь попробует запустить это, а потом исправить.   -  person neuromancer    schedule 22.11.2009


Ответы (1)


RTLD_NEXT доступен в glibc с незапамятных времен.
Вы используете систему Linux (или систему на основе glibc)? Не похоже на это.

Обновление:
RTLD_NEXT - это glibc расширение. Вы не можете использовать ее на cygwin, потому что cygwin! = glibc.
Насколько я понимаю, cygwin также не поддерживает LD_PRELOAD, поэтому даже если вам удастся создать эту библиотеку, она не будет очень полезной.

person Employed Russian    schedule 22.11.2009
comment
@Phenom: ты должен был сказать это раньше; cygwin не поддерживает RTLD_NEXT (см., например, это сообщение lists.zerezo.com/cygwin/msg38882.html с октября 2008 г.) - person Christoph; 22.11.2009