From 6dfde2a47b0d9644275713a96585de442e269bd2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 14 Sep 2009 22:51:35 +0200 Subject: rework dlsym() code and make it entirely compiler clean --- mutrace.c | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) (limited to 'mutrace.c') diff --git a/mutrace.c b/mutrace.c index 299986b..b2763c1 100644 --- a/mutrace.c +++ b/mutrace.c @@ -47,8 +47,6 @@ #define DEBUG_TRAP raise(SIGTRAP) #endif -typedef void (*fnptr_t)(void); - struct mutex_info { pthread_mutex_t *mutex; @@ -110,17 +108,6 @@ static uint64_t nsec_timestamp_setup; static void setup(void) __attribute ((constructor)); static void shutdown(void) __attribute ((destructor)); -/* dlsym() violates ISO C, so confide the breakage into this function - * to avoid warnings. */ - -static inline fnptr_t dlsym_fn(void *handle, const char *symbol, const char *version) { - - if (version) - return (fnptr_t) (long) dlvsym(handle, symbol, version); - else - return (fnptr_t) (long) dlsym(handle, symbol); -} - static pid_t _gettid(void) { return (pid_t) syscall(SYS_gettid); } @@ -158,9 +145,15 @@ static int parse_env(const char *n, unsigned *t) { return 0; } -#define LOAD_FUNC(name, ret, args, version) \ +#define LOAD_FUNC(name) \ + do { \ + *(void**) (&real_##name) = dlsym(RTLD_NEXT, #name); \ + assert(real_##name); \ + } while (false) + +#define LOAD_FUNC_VERSIONED(name, version) \ do { \ - real_##name = (ret (*) args) dlsym_fn(RTLD_NEXT, #name, version); \ + *(void**) (&real_##name) = dlvsym(RTLD_NEXT, #name, version); \ assert(real_##name); \ } while (false) @@ -169,17 +162,21 @@ static void setup(void) { int r; unsigned t; - LOAD_FUNC(pthread_mutex_init, int, (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr), NULL); - LOAD_FUNC(pthread_mutex_destroy, int, (pthread_mutex_t *mutex), NULL); - LOAD_FUNC(pthread_mutex_lock, int, (pthread_mutex_t *mutex), NULL); - LOAD_FUNC(pthread_mutex_trylock, int, (pthread_mutex_t *mutex), NULL); - LOAD_FUNC(pthread_mutex_timedlock, int, (pthread_mutex_t *mutex, const struct timespec *abstime), NULL); - LOAD_FUNC(pthread_mutex_unlock, int, (pthread_mutex_t *mutex), NULL); - LOAD_FUNC(pthread_cond_wait, int, (pthread_cond_t *cond, pthread_mutex_t *mutex), "GLIBC_2.3.2"); - LOAD_FUNC(pthread_cond_timedwait, int, (pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime), "GLIBC_2.3.2"); - LOAD_FUNC(exit, void, (int status), NULL); - LOAD_FUNC(_exit, void, (int status), NULL); - LOAD_FUNC(_Exit, void, (int status), NULL); + LOAD_FUNC(pthread_mutex_init); + LOAD_FUNC(pthread_mutex_destroy); + LOAD_FUNC(pthread_mutex_lock); + LOAD_FUNC(pthread_mutex_trylock); + LOAD_FUNC(pthread_mutex_timedlock); + LOAD_FUNC(pthread_mutex_unlock); + + /* There's some kind of weird incompatibility problem if we + * don't ask for this explicit version of these functions */ + LOAD_FUNC_VERSIONED(pthread_cond_wait, "GLIBC_2.3.2"); + LOAD_FUNC_VERSIONED(pthread_cond_timedwait, "GLIBC_2.3.2"); + + LOAD_FUNC(exit); + LOAD_FUNC(_exit); + LOAD_FUNC(_Exit); t = hash_size; if (parse_env("MUTRACE_HASH_SIZE", &t) < 0 || t <= 0) -- cgit