Commit ed3099c9 authored by Kevin Harms's avatar Kevin Harms
Browse files

Rework how the ldpreload code is initialized. Each function checks to

see if the function is resolved and if not, resolves it at that time.
The other method failed when constructors were called for libraries that
were not linked in so the dlsym lookup failed.


git-svn-id: https://svn.mcs.anl.gov/repos/darshan/trunk@369 3b7491f3-a168-0410-bf4b-c445ed680a29
parent 85a1981a
......@@ -111,7 +111,7 @@ lib/libdarshan-posix.a: lib/darshan-posix.o lib/lookup3.o lib/lookup8.o
ar rcs $@ $^
lib/libdarshan.so: lib/darshan-mpi-io.po lib/darshan-pnetcdf.po lib/darshan-hdf5.po lib/darshan-posix.po lib/lookup3.po lib/lookup8.po
$(CC) $(CFLAGS_MPI_SHARED) -ldl -o $@ $^
gcc $(CFLAGS_MPI_SHARED) -ldl -o $@ $^ -lpthread -lrt
install:: all
install -d $(libdir)
......
......@@ -16,11 +16,25 @@ typedef int herr_t;
#ifdef DARSHAN_PRELOAD
#define __USE_GNU
#include <dlfcn.h>
#include <stdlib.h>
#define DARSHAN_FORWARD_DECL(name,ret,args) \
ret (*__real_ ## name)args = NULL;
#define DARSHAN_DECL(__name) __name
#define MAP_OR_FAIL(func) \
if (!(__real_ ## func)) \
{ \
__real_ ## func = dlsym(RTLD_NEXT, #func); \
if(!(__real_ ## func)) { \
fprintf(stderr, "Darshan failed to map symbol: %s\n", #func); \
exit(1); \
} \
}
#else
#define DARSHAN_FORWARD_DECL(name,ret,args) \
......@@ -28,33 +42,14 @@ typedef int herr_t;
#define DARSHAN_DECL(__name) __wrap_ ## __name
#define MAP_OR_FAIL(func)
#endif
DARSHAN_FORWARD_DECL(H5Fcreate, hid_t, (const char *filename, unsigned flags, hid_t create_plist, hid_t access_plist));
DARSHAN_FORWARD_DECL(H5Fopen, hid_t, (const char *filename, unsigned flags, hid_t access_plist));
DARSHAN_FORWARD_DECL(H5Fclose, herr_t, (hid_t file_id));
#ifdef DARSHAN_PRELOAD
#define __USE_GNU
#include <dlfcn.h>
#include <stdlib.h>
static void __attribute__ ((constructor)) darshan_ldpreload_init(void)
{
#define MAP_OR_FAIL(func) \
__real_ ## func = dlsym(RTLD_NEXT, #func); \
if(!(__real_ ## func)) { \
fprintf(stderr, "Darshan failed to map symbol: %s\n", #func); \
exit(1); \
}
MAP_OR_FAIL(H5Fcreate);
MAP_OR_FAIL(H5Fopen);
MAP_OR_FAIL(H5Fclose);
return;
}
#endif
static struct darshan_file_runtime* darshan_file_by_hid(int hid);
hid_t DARSHAN_DECL(H5Fcreate)(const char *filename, unsigned flags,
......@@ -65,6 +60,8 @@ hid_t DARSHAN_DECL(H5Fcreate)(const char *filename, unsigned flags,
char* tmp;
int hash_index;
MAP_OR_FAIL(H5Fcreate);
ret = __real_H5Fcreate(filename, flags, create_plist, access_plist);
if(ret >= 0)
{
......@@ -106,6 +103,8 @@ hid_t DARSHAN_DECL(H5Fopen)(const char *filename, unsigned flags,
char* tmp;
int hash_index;
MAP_OR_FAIL(H5Fopen);
ret = __real_H5Fopen(filename, flags, access_plist);
if(ret >= 0)
{
......@@ -148,6 +147,8 @@ herr_t DARSHAN_DECL(H5Fclose)(hid_t file_id)
int tmp_hid = file_id;
int ret;
MAP_OR_FAIL(H5Fclose);
ret = __real_H5Fclose(file_id);
CP_LOCK();
......
This diff is collapsed.
......@@ -11,12 +11,25 @@
#include "darshan-config.h"
#ifdef DARSHAN_PRELOAD
#define __USE_GNU
#include <dlfcn.h>
#include <stdlib.h>
#define DARSHAN_FORWARD_DECL(name,ret,args) \
ret (*__real_ ## name)args = NULL;
#define DARSHAN_DECL(__name) __name
#define MAP_OR_FAIL(func) \
if (!(__real_ ## func)) \
{ \
__real_ ## func = dlsym(RTLD_NEXT, #func); \
if(!(__real_ ## func)) { \
fprintf(stderr, "Darshan failed to map symbol: %s\n", #func); \
exit(1); \
} \
}
#else
#define DARSHAN_FORWARD_DECL(name,ret,args) \
......@@ -24,33 +37,14 @@
#define DARSHAN_DECL(__name) __wrap_ ## __name
#define MAP_OR_FAIL(func)
#endif
DARSHAN_FORWARD_DECL(ncmpi_create, int, (MPI_Comm comm, const char *path, int cmode, MPI_Info info, int *ncidp));
DARSHAN_FORWARD_DECL(ncmpi_open, int, (MPI_Comm comm, const char *path, int omode, MPI_Info info, int *ncidp));
DARSHAN_FORWARD_DECL(ncmpi_close, int, (int ncid));
#ifdef DARSHAN_PRELOAD
#define __USE_GNU
#include <dlfcn.h>
#include <stdlib.h>
static void __attribute__ ((constructor)) darshan_ldpreload_init(void)
{
#define MAP_OR_FAIL(func) \
__real_ ## func = dlsym(RTLD_NEXT, #func); \
if(!(__real_ ## func)) { \
fprintf(stderr, "Darshan failed to map symbol: %s\n", #func); \
exit(1); \
}
MAP_OR_FAIL(ncmpi_create);
MAP_OR_FAIL(ncmpi_open);
MAP_OR_FAIL(ncmpi_close);
return;
}
#endif
static struct darshan_file_runtime* darshan_file_by_ncid(int ncid);
int DARSHAN_DECL(ncmpi_create)(MPI_Comm comm, const char *path,
......@@ -62,6 +56,8 @@ int DARSHAN_DECL(ncmpi_create)(MPI_Comm comm, const char *path,
int comm_size;
int hash_index;
MAP_OR_FAIL(ncmpi_create);
ret = __real_ncmpi_create(comm, path, cmode, info, ncidp);
if(ret == 0)
{
......@@ -114,6 +110,8 @@ int DARSHAN_DECL(ncmpi_open)(MPI_Comm comm, const char *path,
int comm_size;
int hash_index;
MAP_OR_FAIL(ncmpi_open);
ret = __real_ncmpi_open(comm, path, omode, info, ncidp);
if(ret == 0)
{
......@@ -165,6 +163,8 @@ int DARSHAN_DECL(ncmpi_close)(int ncid)
int tmp_ncid = ncid;
int ret;
MAP_OR_FAIL(ncmpi_close);
ret = __real_ncmpi_close(ncid);
CP_LOCK();
......
......@@ -29,12 +29,31 @@ typedef int64_t off64_t;
extern char* __progname_full;
#ifdef DARSHAN_PRELOAD
#define __USE_GNU
#include <dlfcn.h>
#include <stdlib.h>
#define DARSHAN_FORWARD_DECL(name,ret,args) \
ret (*__real_ ## name)args = NULL;
#define DARSHAN_DECL(__name) __name
#define DARSHAN_MPI_CALL(func) __real_ ## func
#define MAP_OR_FAIL(func) \
fprintf(stderr, "Trapped: %s\n", #func); \
if (!(__real_ ## func)) \
{ \
__real_ ## func = dlsym(RTLD_NEXT, #func); \
if(!(__real_ ## func)) { \
fprintf(stderr, "Darshan failed to map symbol: %s\n", #func); \
exit(1); \
} \
}
extern double __real_PMPI_Wtime(void);
#else
#define DARSHAN_FORWARD_DECL(name,ret,args) \
......@@ -42,6 +61,10 @@ extern char* __progname_full;
#define DARSHAN_DECL(__name) __wrap_ ## __name
#define MAP_OR_FAIL(func)
#define DARSHAN_MPI_CALL(func) func
#endif
DARSHAN_FORWARD_DECL(creat, int, (const char* path, mode_t mode));
......@@ -77,55 +100,6 @@ DARSHAN_FORWARD_DECL(fseek, int, (FILE *stream, long offset, int whence));
DARSHAN_FORWARD_DECL(fsync, int, (int fd));
DARSHAN_FORWARD_DECL(fdatasync, int, (int fd));
#ifdef DARSHAN_PRELOAD
#define __USE_GNU
#include <dlfcn.h>
#include <stdlib.h>
static void __attribute__ ((constructor)) darshan_ldpreload_init(void)
{
#define MAP_OR_FAIL(func) \
__real_ ## func = dlsym(RTLD_NEXT, #func); \
if(!(__real_ ## func)) { \
fprintf(stderr, "Darshan failed to map symbol: %s\n", #func); \
exit(1); \
}
MAP_OR_FAIL(creat);
MAP_OR_FAIL(creat64);
MAP_OR_FAIL(open);
MAP_OR_FAIL(open64);
MAP_OR_FAIL(close);
MAP_OR_FAIL(write);
MAP_OR_FAIL(read);
MAP_OR_FAIL(lseek);
MAP_OR_FAIL(lseek64);
MAP_OR_FAIL(pread);
MAP_OR_FAIL(pread64);
MAP_OR_FAIL(pwrite);
MAP_OR_FAIL(pwrite64);
MAP_OR_FAIL(readv);
MAP_OR_FAIL(writev);
MAP_OR_FAIL(__fxstat);
MAP_OR_FAIL(__fxstat64);
MAP_OR_FAIL(__lxstat);
MAP_OR_FAIL(__lxstat64);
MAP_OR_FAIL(__xstat);
MAP_OR_FAIL(__xstat64);
MAP_OR_FAIL(mmap);
MAP_OR_FAIL(mmap64);
MAP_OR_FAIL(fopen);
MAP_OR_FAIL(fopen64);
MAP_OR_FAIL(close);
MAP_OR_FAIL(fread);
MAP_OR_FAIL(fwrite);
MAP_OR_FAIL(fseek);
MAP_OR_FAIL(fsync);
MAP_OR_FAIL(fdatasync);
return;
}
#endif
pthread_mutex_t cp_mutex = PTHREAD_MUTEX_INITIALIZER;
struct darshan_job_runtime* darshan_global_job = NULL;
static int my_rank = -1;
......@@ -147,6 +121,8 @@ static char* exclusions[] = {
NULL
};
static double posix_wtime(void);
static void cp_access_counter(struct darshan_file_runtime* file, ssize_t size, enum cp_counter_type type);
#define CP_RECORD_WRITE(__ret, __fd, __count, __update_offset, __aligned, __stream_flag, __tm1, __tm2) do{ \
......@@ -290,7 +266,7 @@ static void cp_access_counter(struct darshan_file_runtime* file, ssize_t size,
else \
CP_INC(file, CP_POSIX_OPENS, 1); \
if(CP_F_VALUE(file, CP_F_OPEN_TIMESTAMP) == 0) \
CP_F_SET(file, CP_F_OPEN_TIMESTAMP, MPI_Wtime()); \
CP_F_SET(file, CP_F_OPEN_TIMESTAMP, posix_wtime()); \
CP_F_INC(file, CP_F_POSIX_META_TIME, (__tm2-__tm1)); \
hash_index = file->fd & CP_HASH_MASK; \
file->fd_prev = NULL; \
......@@ -308,6 +284,8 @@ int DARSHAN_DECL(close)(int fd)
double tm1, tm2;
int ret;
MAP_OR_FAIL(close);
tm1 = darshan_wtime();
ret = __real_close(fd);
tm2 = darshan_wtime();
......@@ -319,7 +297,7 @@ int DARSHAN_DECL(close)(int fd)
file->fd = -1;
file->last_byte_written = 0;
file->last_byte_read = 0;
CP_F_SET(file, CP_F_CLOSE_TIMESTAMP, MPI_Wtime());
CP_F_SET(file, CP_F_CLOSE_TIMESTAMP, posix_wtime());
CP_F_INC(file, CP_F_POSIX_META_TIME, (tm2-tm1));
if(file->fd_prev == NULL)
{
......@@ -353,6 +331,8 @@ int DARSHAN_DECL(fclose)(FILE *fp)
double tm1, tm2;
int ret;
MAP_OR_FAIL(fclose);
tm1 = darshan_wtime();
ret = __real_fclose(fp);
tm2 = darshan_wtime();
......@@ -364,7 +344,7 @@ int DARSHAN_DECL(fclose)(FILE *fp)
file->fd = -1;
file->last_byte_written = 0;
file->last_byte_read = 0;
CP_F_SET(file, CP_F_CLOSE_TIMESTAMP, MPI_Wtime());
CP_F_SET(file, CP_F_CLOSE_TIMESTAMP, posix_wtime());
CP_F_INC(file, CP_F_POSIX_META_TIME, (tm2-tm1));
if(file->fd_prev == NULL)
{
......@@ -397,6 +377,8 @@ int DARSHAN_DECL(fsync)(int fd)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(fsync);
tm1 = darshan_wtime();
ret = __real_fsync(fd);
tm2 = darshan_wtime();
......@@ -422,6 +404,8 @@ int DARSHAN_DECL(fdatasync)(int fd)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(fdatasync);
tm1 = darshan_wtime();
ret = __real_fdatasync(fd);
tm2 = darshan_wtime();
......@@ -447,6 +431,8 @@ void* DARSHAN_DECL(mmap64)(void *addr, size_t length, int prot, int flags,
void* ret;
struct darshan_file_runtime* file;
MAP_OR_FAIL(mmap64);
ret = __real_mmap64(addr, length, prot, flags, fd, offset);
if(ret == MAP_FAILED)
return(ret);
......@@ -469,6 +455,8 @@ void* DARSHAN_DECL(mmap)(void *addr, size_t length, int prot, int flags,
void* ret;
struct darshan_file_runtime* file;
MAP_OR_FAIL(mmap);
ret = __real_mmap(addr, length, prot, flags, fd, offset);
if(ret == MAP_FAILED)
return(ret);
......@@ -489,6 +477,8 @@ int DARSHAN_DECL(creat)(const char* path, mode_t mode)
int ret;
double tm1, tm2;
MAP_OR_FAIL(creat);
tm1 = darshan_wtime();
ret = __real_creat(path, mode);
tm2 = darshan_wtime();
......@@ -505,6 +495,8 @@ int DARSHAN_DECL(creat64)(const char* path, mode_t mode)
int ret;
double tm1, tm2;
MAP_OR_FAIL(creat64);
tm1 = darshan_wtime();
ret = __real_creat64(path, mode);
tm2 = darshan_wtime();
......@@ -522,6 +514,8 @@ int DARSHAN_DECL(open64)(const char* path, int flags, ...)
int ret;
double tm1, tm2;
MAP_OR_FAIL(open64);
if (flags & O_CREAT)
{
va_list arg;
......@@ -553,6 +547,8 @@ int DARSHAN_DECL(open)(const char *path, int flags, ...)
int ret;
double tm1, tm2;
MAP_OR_FAIL(open);
if (flags & O_CREAT)
{
va_list arg;
......@@ -584,6 +580,8 @@ FILE* DARSHAN_DECL(fopen64)(const char *path, const char *mode)
int fd;
double tm1, tm2;
MAP_OR_FAIL(fopen64);
tm1 = darshan_wtime();
ret = __real_fopen64(path, mode);
tm2 = darshan_wtime();
......@@ -605,6 +603,8 @@ FILE* DARSHAN_DECL(fopen)(const char *path, const char *mode)
int fd;
double tm1, tm2;
MAP_OR_FAIL(fopen);
tm1 = darshan_wtime();
ret = __real_fopen(path, mode);
tm2 = darshan_wtime();
......@@ -626,6 +626,8 @@ int DARSHAN_DECL(__xstat64)(int vers, const char *path, struct stat64 *buf)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(__xstat64);
tm1 = darshan_wtime();
ret = __real___xstat64(vers, path, buf);
tm2 = darshan_wtime();
......@@ -649,6 +651,8 @@ int DARSHAN_DECL(__lxstat64)(int vers, const char *path, struct stat64 *buf)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(__lxstat64);
tm1 = darshan_wtime();
ret = __real___lxstat64(vers, path, buf);
tm2 = darshan_wtime();
......@@ -672,6 +676,8 @@ int DARSHAN_DECL(__fxstat64)(int vers, int fd, struct stat64 *buf)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(__fxstat64);
tm1 = darshan_wtime();
ret = __real___fxstat64(vers, fd, buf);
tm2 = darshan_wtime();
......@@ -700,6 +706,8 @@ int DARSHAN_DECL(__xstat)(int vers, const char *path, struct stat *buf)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(__xstat);
tm1 = darshan_wtime();
ret = __real___xstat(vers, path, buf);
tm2 = darshan_wtime();
......@@ -723,6 +731,8 @@ int DARSHAN_DECL(__lxstat)(int vers, const char *path, struct stat *buf)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(__lxstat);
tm1 = darshan_wtime();
ret = __real___lxstat(vers, path, buf);
tm2 = darshan_wtime();
......@@ -746,6 +756,8 @@ int DARSHAN_DECL(__fxstat)(int vers, int fd, struct stat *buf)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(__fxstat);
tm1 = darshan_wtime();
ret = __real___fxstat(vers, fd, buf);
tm2 = darshan_wtime();
......@@ -773,6 +785,8 @@ ssize_t DARSHAN_DECL(pread64)(int fd, void *buf, size_t count, off64_t offset)
int aligned_flag = 0;
double tm1, tm2;
MAP_OR_FAIL(pread64);
if((unsigned long)buf % darshan_mem_alignment == 0)
aligned_flag = 1;
......@@ -791,6 +805,8 @@ ssize_t DARSHAN_DECL(pread)(int fd, void *buf, size_t count, off_t offset)
int aligned_flag = 0;
double tm1, tm2;
MAP_OR_FAIL(pread);
if((unsigned long)buf % darshan_mem_alignment == 0)
aligned_flag = 1;
......@@ -810,6 +826,8 @@ ssize_t DARSHAN_DECL(pwrite)(int fd, const void *buf, size_t count, off_t offset
int aligned_flag = 0;
double tm1, tm2;
MAP_OR_FAIL(pwrite);
if((unsigned long)buf % darshan_mem_alignment == 0)
aligned_flag = 1;
......@@ -828,6 +846,8 @@ ssize_t DARSHAN_DECL(pwrite64)(int fd, const void *buf, size_t count, off64_t of
int aligned_flag = 0;
double tm1, tm2;
MAP_OR_FAIL(pwrite64);
if((unsigned long)buf % darshan_mem_alignment == 0)
aligned_flag = 1;
......@@ -847,6 +867,8 @@ ssize_t DARSHAN_DECL(readv)(int fd, const struct iovec *iov, int iovcnt)
int i;
double tm1, tm2;
MAP_OR_FAIL(readv);
for(i=0; i<iovcnt; i++)
{
if(((unsigned long)iov[i].iov_base % darshan_mem_alignment) != 0)
......@@ -869,6 +891,8 @@ ssize_t DARSHAN_DECL(writev)(int fd, const struct iovec *iov, int iovcnt)
int i;
double tm1, tm2;
MAP_OR_FAIL(writev);
for(i=0; i<iovcnt; i++)
{
if(!((unsigned long)iov[i].iov_base % darshan_mem_alignment == 0))
......@@ -890,6 +914,8 @@ size_t DARSHAN_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
int aligned_flag = 0;
double tm1, tm2;
MAP_OR_FAIL(fread);
if((unsigned long)ptr % darshan_mem_alignment == 0)
aligned_flag = 1;
......@@ -911,6 +937,8 @@ ssize_t DARSHAN_DECL(read)(int fd, void *buf, size_t count)
int aligned_flag = 0;
double tm1, tm2;
MAP_OR_FAIL(read);
if((unsigned long)buf % darshan_mem_alignment == 0)
aligned_flag = 1;
......@@ -929,6 +957,8 @@ ssize_t DARSHAN_DECL(write)(int fd, const void *buf, size_t count)
int aligned_flag = 0;
double tm1, tm2;
MAP_OR_FAIL(write);
if((unsigned long)buf % darshan_mem_alignment == 0)
aligned_flag = 1;
......@@ -947,6 +977,8 @@ size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *st
int aligned_flag = 0;
double tm1, tm2;
MAP_OR_FAIL(fwrite);
if((unsigned long)ptr % darshan_mem_alignment == 0)
aligned_flag = 1;
......@@ -968,6 +1000,8 @@ off64_t DARSHAN_DECL(lseek64)(int fd, off64_t offset, int whence)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(lseek64);
tm1 = darshan_wtime();
ret = __real_lseek64(fd, offset, whence);
tm2 = darshan_wtime();
......@@ -992,6 +1026,8 @@ off_t DARSHAN_DECL(lseek)(int fd, off_t offset, int whence)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(lseek);
tm1 = darshan_wtime();
ret = __real_lseek(fd, offset, whence);
tm2 = darshan_wtime();
......@@ -1016,6 +1052,8 @@ int DARSHAN_DECL(fseek)(FILE *stream, long offset, int whence)
struct darshan_file_runtime* file;
double tm1, tm2;
MAP_OR_FAIL(fseek);
tm1 = darshan_wtime();
ret = __real_fseek(stream, offset, whence);
tm2 = darshan_wtime();
......@@ -1662,6 +1700,11 @@ void darshan_search_bench(int argc, char** argv, int iters)
}
#endif
static double posix_wtime(void)
{
return DARSHAN_MPI_CALL(PMPI_Wtime)();
}
double darshan_wtime(void)
{
if(!darshan_global_job || darshan_global_job->flags & CP_FLAG_NOTIMING)
......@@ -1669,7 +1712,7 @@ double darshan_wtime(void)
return(0);
}
return(MPI_Wtime());
return(posix_wtime());
}
/*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment