gprofng: 30089 [display text] Invalid number of threads
The real problem is that libcollector doesn't interpose thread_create@GLIBC_2.34 We interpose a lot of libC functions (dlopen, fork, pthread_create, etc.). Some of these functions have versions. For example, dlopen@GLIBC_2.34, dlopen@GLIBC_2.17, dlopen@GLIBC_2.2.5, etc. We have to interpose each of the functions because we don't know which version of libC will be used during profiling. Historically, we have used three versions of scripts (mapfile.aarch64-Linux, mapfile.amd64-Linux, mapfile.intel-Linux). Three are not needed. One is enough The fixes below include: - merged all version symbols into one version script. - added new version symbols which are defined in latest versions of libC. - removed unused defines and duplicated code. - added the DCL_FUNC_VER macro to define the version symbols. Tested on x86_64 and aarch64 (OL8/OL9). No regression. gprofng/ChangeLog 2023-03-23 Vladimir Mezentsev <vladimir.mezentsev@oracle.com> PR gprofng/30089 * libcollector/Makefile.am: Use libgprofng.ver instead of mapfile.* * libcollector/configure.ac: Delete GPROFNG_VARIANT. * src/collector_module.h: Move the SYMVER_ATTRIBUTE macro to collector.h * libcollector/collector.h: Add macros (SYMVER_ATTRIBUTE, DCL_FUNC_VER). Remove unused defines. * libcollector/dispatcher.c: Interpose functions from libC. Clean up the old code. * libcollector/iotrace.c: Likewise. * libcollector/libcol_util.c: Likewise. * libcollector/linetrace.c: Likewise. * libcollector/mmaptrace.c: Likewise. * libcollector/synctrace.c: Likewise. * libcollector/libgprofng.ver: New file. * libcollector/Makefile.in: Rebuild. * libcollector/configure: Rebuild. * libcollector/mapfile.aarch64-Linux: Removed. * libcollector/mapfile.amd64-Linux: Removed. * libcollector/mapfile.intel-Linux: Removed. * libcollector/mapfile.sparc-Linux: Removed. * libcollector/mapfile.sparcv9-Linux: Removed.
This commit is contained in:
parent
57573e54af
commit
66f76c545b
@ -19,8 +19,6 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
ACLOCAL_AMFLAGS = -I . -I ../..
|
||||
|
||||
GPROFNG_VARIANT = @GPROFNG_VARIANT@
|
||||
|
||||
CSOURCES = \
|
||||
gethrtime.c \
|
||||
dispatcher.c \
|
||||
@ -46,7 +44,7 @@ AM_CPPFLAGS = $(GPROFNG_CPPFLAGS) -I.. -I$(srcdir) \
|
||||
-I$(srcdir)/../common -I$(srcdir)/../src \
|
||||
-I$(srcdir)/../../include
|
||||
AM_LDFLAGS = -module -avoid-version \
|
||||
-Wl,--version-script,$(srcdir)/mapfile.$(GPROFNG_VARIANT) \
|
||||
-Wl,--version-script,$(srcdir)/libgprofng.ver \
|
||||
$(LD_NO_AS_NEEDED) -Wl,-lrt -Wl,-ldl
|
||||
|
||||
myincludedir = @includedir@
|
||||
|
@ -325,7 +325,6 @@ EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GPROFNG_NO_NONNULL_COMPARE_CFLAGS = @GPROFNG_NO_NONNULL_COMPARE_CFLAGS@
|
||||
GPROFNG_VARIANT = @GPROFNG_VARIANT@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
@ -448,7 +447,7 @@ AM_CPPFLAGS = $(GPROFNG_CPPFLAGS) -I.. -I$(srcdir) \
|
||||
-I$(srcdir)/../../include
|
||||
|
||||
AM_LDFLAGS = -module -avoid-version \
|
||||
-Wl,--version-script,$(srcdir)/mapfile.$(GPROFNG_VARIANT) \
|
||||
-Wl,--version-script,$(srcdir)/libgprofng.ver \
|
||||
$(LD_NO_AS_NEEDED) -Wl,-lrt -Wl,-ldl
|
||||
|
||||
myincludedir = @includedir@
|
||||
|
@ -32,9 +32,25 @@
|
||||
#define CALL_REAL(x) (__real_##x)
|
||||
#define NULL_PTR(x) (__real_##x == NULL)
|
||||
|
||||
#define SYS_LIBC_NAME "libc.so.6"
|
||||
|
||||
#ifdef __has_attribute
|
||||
#if __has_attribute (__symver__)
|
||||
#define SYMVER_ATTRIBUTE(sym, symver) __attribute__ ((__symver__ (#symver)))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SYMVER_ATTRIBUTE
|
||||
# define SYMVER_ATTRIBUTE(sym, symver) __asm__(".symver " #sym "," #symver);
|
||||
#endif
|
||||
|
||||
#if defined(__MUSL_LIBC)
|
||||
#define dlvsym(f, nm, v) dlsym (f, nm)
|
||||
#define SIGEV_THREAD_ID 4
|
||||
#define DCL_FUNC_VER(REAL_DCL, sym, ver)
|
||||
#else
|
||||
#define DCL_FUNC_VER(REAL_DCL, sym, ver) \
|
||||
SYMVER_ATTRIBUTE (__collector_ ## sym, ver) \
|
||||
REAL_DCL (__collector_ ## sym, CALL_REAL (sym))
|
||||
#endif
|
||||
|
||||
extern hrtime_t __collector_start_time;
|
||||
@ -51,7 +67,8 @@ extern int __collector_write_packet (struct DataHandle*, CM_Packet*);
|
||||
extern int __collector_write_string (struct DataHandle*, char*, int);
|
||||
extern FrameInfo __collector_get_frame_info (hrtime_t, int, void *);
|
||||
extern FrameInfo __collector_getUID (CM_Array *arg, FrameInfo uid);
|
||||
extern int __collector_getStackTrace (void *buf, int size, void *bptr, void *eptr, void *arg);
|
||||
extern int __collector_getStackTrace (void *buf, int size, void *bptr,
|
||||
void *eptr, void *arg);
|
||||
extern void *__collector_ext_return_address (unsigned level);
|
||||
extern void __collector_mmap_fork_child_cleanup ();
|
||||
|
||||
@ -83,10 +100,8 @@ extern void __collector_ext_dispatcher_restart ();
|
||||
extern void __collector_ext_dispatcher_deinstall ();
|
||||
extern void __collector_ext_usage_sample (Smpl_type type, char *name);
|
||||
extern void __collector_ext_profile_handler (siginfo_t *, ucontext_t *);
|
||||
extern int __collector_ext_clone_pthread (int (*fn)(void *), void *child_stack, int flags, void *arg,
|
||||
va_list va /* pid_t *ptid, struct user_desc *tlspid_t *" ctid" */);
|
||||
|
||||
/* D-light related functions */
|
||||
extern int __collector_ext_clone_pthread (int (*fn)(void *), void *child_stack,
|
||||
int flags, void *arg, va_list va);
|
||||
extern int __collector_sigprof_install ();
|
||||
extern int __collector_ext_hwc_active ();
|
||||
extern void __collector_ext_hwc_check (siginfo_t *, ucontext_t *);
|
||||
@ -98,7 +113,8 @@ extern int (*__collector_VM_ReadByteInstruction)(unsigned char *);
|
||||
extern int (*__collector_omp_stack_trace)(char*, int, hrtime_t, void*);
|
||||
extern hrtime_t (*__collector_gethrtime)();
|
||||
extern int (*__collector_mpi_stack_trace)(char*, int, hrtime_t);
|
||||
extern int __collector_open_experiment (const char *exp, const char *par, sp_origin_t origin);
|
||||
extern int __collector_open_experiment (const char *exp, const char *par,
|
||||
sp_origin_t origin);
|
||||
extern void __collector_suspend_experiment (char *why);
|
||||
extern void __collector_resume_experiment ();
|
||||
extern void __collector_clean_state ();
|
||||
@ -198,56 +214,4 @@ enum
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
// To find the glibc version:
|
||||
// objdump -T /lib*/*so /lib*/*/*.so | grep popen
|
||||
// IMPORTANT: The GLIBC_* versions below must match those in mapfile.<variant>
|
||||
#if ARCH(Aarch64)
|
||||
#define SYS_LIBC_NAME "libc.so.6"
|
||||
#define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.17"
|
||||
#define SYS_DLOPEN_VERSION "GLIBC_2.17"
|
||||
#define SYS_POPEN_VERSION "GLIBC_2.17"
|
||||
#define SYS_FOPEN_X_VERSION "GLIBC_2.17"
|
||||
#define SYS_FGETPOS_X_VERSION "GLIBC_2.17"
|
||||
|
||||
#elif ARCH(Intel)
|
||||
#define SYS_LIBC_NAME "libc.so.6"
|
||||
#define SYS_POSIX_SPAWN_VERSION "GLIBC_2.15"
|
||||
#if WSIZE(32)
|
||||
#define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.1"
|
||||
#define SYS_DLOPEN_VERSION "GLIBC_2.1"
|
||||
#define SYS_POPEN_VERSION "GLIBC_2.1"
|
||||
#define SYS_TIMER_X_VERSION "GLIBC_2.2"
|
||||
#define SYS_FOPEN_X_VERSION "GLIBC_2.1"
|
||||
#define SYS_FGETPOS_X_VERSION "GLIBC_2.2"
|
||||
#define SYS_FGETPOS64_X_VERSION "GLIBC_2.2"
|
||||
#define SYS_OPEN64_X_VERSION "GLIBC_2.2"
|
||||
#define SYS_PREAD_X_VERSION "GLIBC_2.2"
|
||||
#define SYS_PWRITE_X_VERSION "GLIBC_2.2"
|
||||
#define SYS_PWRITE64_X_VERSION "GLIBC_2.2"
|
||||
#else /* WSIZE(64) */
|
||||
#define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.2.5"
|
||||
#define SYS_DLOPEN_VERSION "GLIBC_2.2.5"
|
||||
#define SYS_POPEN_VERSION "GLIBC_2.2.5"
|
||||
#define SYS_TIMER_X_VERSION "GLIBC_2.3.3"
|
||||
#define SYS_FOPEN_X_VERSION "GLIBC_2.2.5"
|
||||
#define SYS_FGETPOS_X_VERSION "GLIBC_2.2.5"
|
||||
#endif
|
||||
|
||||
#elif ARCH(SPARC)
|
||||
#define SYS_LIBC_NAME "libc.so.6"
|
||||
#define SYS_DLOPEN_VERSION "GLIBC_2.1"
|
||||
#if WSIZE(32)
|
||||
#define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.1"
|
||||
#define SYS_POPEN_VERSION "GLIBC_2.1"
|
||||
#define SYS_FOPEN_X_VERSION "GLIBC_2.1"
|
||||
#define SYS_FGETPOS_X_VERSION "GLIBC_2.2"
|
||||
#else /* WSIZE(64) */
|
||||
#define SYS_PTHREAD_CREATE_VERSION "GLIBC_2.2"
|
||||
#define SYS_POPEN_VERSION "GLIBC_2.2"
|
||||
#define SYS_TIMER_X_VERSION "GLIBC_2.3.3"
|
||||
#define SYS_FOPEN_X_VERSION "GLIBC_2.2"
|
||||
#define SYS_FGETPOS_X_VERSION "GLIBC_2.2"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
22
gprofng/libcollector/configure
vendored
22
gprofng/libcollector/configure
vendored
@ -634,7 +634,6 @@ am__EXEEXT_TRUE
|
||||
LTLIBOBJS
|
||||
LIBOBJS
|
||||
GPROFNG_NO_NONNULL_COMPARE_CFLAGS
|
||||
GPROFNG_VARIANT
|
||||
CXXCPP
|
||||
OTOOL64
|
||||
OTOOL
|
||||
@ -12064,7 +12063,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12067 "configure"
|
||||
#line 12066 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -12170,7 +12169,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12173 "configure"
|
||||
#line 12172 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -15475,23 +15474,6 @@ if test "$enable_shared" != "yes"; then
|
||||
$as_echo "$as_me: WARNING: Cannot set --enable-shared for gprofng/libcollector. Profiling will be unavailable." >&2;}
|
||||
fi
|
||||
|
||||
GPROFNG_VARIANT=unknown
|
||||
x=`echo | $CC $CFLAGS -dM -E - | grep -w __x86_64`
|
||||
if test -n "$x"; then
|
||||
GPROFNG_VARIANT=amd64-Linux
|
||||
else
|
||||
x=`echo | $CC $CFLAGS -dM -E - | grep -w __i386__`
|
||||
if test -n "$x"; then
|
||||
GPROFNG_VARIANT=intel-Linux
|
||||
else
|
||||
x=`echo | $CC $CFLAGS -dM -E - | grep -w __aarch64__`
|
||||
if test -n "$x"; then
|
||||
GPROFNG_VARIANT=aarch64-Linux
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
|
@ -41,23 +41,6 @@ if test "$enable_shared" != "yes"; then
|
||||
AC_MSG_WARN([Cannot set --enable-shared for gprofng/libcollector. Profiling will be unavailable.])
|
||||
fi
|
||||
|
||||
GPROFNG_VARIANT=unknown
|
||||
x=`echo | $CC $CFLAGS -dM -E - | grep -w __x86_64`
|
||||
if test -n "$x"; then
|
||||
GPROFNG_VARIANT=amd64-Linux
|
||||
else
|
||||
x=`echo | $CC $CFLAGS -dM -E - | grep -w __i386__`
|
||||
if test -n "$x"; then
|
||||
GPROFNG_VARIANT=intel-Linux
|
||||
else
|
||||
x=`echo | $CC $CFLAGS -dM -E - | grep -w __aarch64__`
|
||||
if test -n "$x"; then
|
||||
GPROFNG_VARIANT=aarch64-Linux
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(GPROFNG_VARIANT)
|
||||
|
||||
ACX_PROG_CC_WARNING_OPTS([-Wno-nonnull-compare], [GPROFNG_NO_NONNULL_COMPARE_CFLAGS])
|
||||
AC_SUBST(GPROFNG_NO_NONNULL_COMPARE_CFLAGS)
|
||||
|
||||
|
@ -63,19 +63,39 @@ static int (*__real_timer_settime) (timer_t timerid, int flags,
|
||||
static int (*__real_timer_delete) (timer_t timerid) = NULL;
|
||||
static int (*__real_timer_gettime) (timer_t timerid,
|
||||
struct itimerspec *curr_value) = NULL;
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
|
||||
static int (*__real_pthread_create_2_34) (pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg) = NULL;
|
||||
static int (*__real_pthread_create_2_17) (pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg) = NULL;
|
||||
static int (*__real_pthread_create_2_2_5) (pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg) = NULL;
|
||||
static int (*__real_pthread_create_2_1) (pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg) = NULL;
|
||||
static int (*__real_pthread_create_2_0) (pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg) = NULL;
|
||||
#elif ARCH(Intel) && WSIZE(64)
|
||||
|
||||
static int (*__real_timer_create_2_34) (clockid_t clockid,
|
||||
struct sigevent *sevp, timer_t *timerid) = NULL;
|
||||
static int (*__real_timer_create_2_17) (clockid_t clockid,
|
||||
struct sigevent *sevp, timer_t *timerid) = NULL;
|
||||
static int (*__real_timer_create_2_3_3) (clockid_t clockid,
|
||||
struct sigevent *sevp, timer_t *timerid) = NULL;
|
||||
static int (*__real_timer_create_2_2_5) (clockid_t clockid,
|
||||
struct sigevent *sevp, timer_t *timerid) = NULL;
|
||||
#endif
|
||||
static int (*__real_timer_create_2_2) (clockid_t clockid,
|
||||
struct sigevent *sevp, timer_t *timerid) = NULL;
|
||||
|
||||
int (*__real_pthread_sigmask_2_32) (int, const sigset_t *, sigset_t *) = NULL;
|
||||
int (*__real_pthread_sigmask_2_17) (int, const sigset_t *, sigset_t *) = NULL;
|
||||
int (*__real_pthread_sigmask_2_2_5) (int, const sigset_t *, sigset_t *) = NULL;
|
||||
int (*__real_pthread_sigmask_2_0) (int, const sigset_t *, sigset_t *) = NULL;
|
||||
|
||||
|
||||
/* Original SIGPROF handler which will be replaced with the dispatcher. Used
|
||||
* to properly interact with libaio, which uses SIGPROF as its SIGAIOCANCEL. */
|
||||
@ -637,12 +657,6 @@ protect_profiling_signals (sigset_t* lset)
|
||||
}
|
||||
}
|
||||
|
||||
#define SYS_SETITIMER_NAME "setitimer"
|
||||
#define SYS_SIGACTION_NAME "sigaction"
|
||||
#define SYS_SIGPROCMASK_NAME "sigprocmask"
|
||||
#define SYS_PTHREAD_SIGMASK "pthread_sigmask"
|
||||
#define SYS_THR_SIGSETMASK "thr_sigsetmask"
|
||||
|
||||
static int
|
||||
init_interposition_intf ()
|
||||
{
|
||||
@ -652,15 +666,10 @@ init_interposition_intf ()
|
||||
/* Linux requires RTLD_LAZY, Solaris can do just RTLD_NOLOAD */
|
||||
void *handle = dlopen (SYS_LIBC_NAME, RTLD_LAZY | RTLD_NOLOAD);
|
||||
|
||||
#if ARCH(SPARC) && WSIZE(64)
|
||||
/* dlopen a bogus path to avoid CR 23608692 */
|
||||
dlopen ("/bogus_path_for_23608692_workaround/", RTLD_LAZY | RTLD_NOLOAD);
|
||||
#endif
|
||||
__real_setitimer = dlsym (RTLD_NEXT, SYS_SETITIMER_NAME);
|
||||
|
||||
__real_setitimer = dlsym (RTLD_NEXT, "setitimer");
|
||||
if (__real_setitimer == NULL)
|
||||
{
|
||||
__real_setitimer = dlsym (RTLD_DEFAULT, SYS_SETITIMER_NAME);
|
||||
__real_setitimer = dlsym (RTLD_DEFAULT, "setitimer");
|
||||
if (__real_setitimer == NULL)
|
||||
{
|
||||
TprintfT (DBG_LT2, "init_interposition_intf() setitimer not found\n");
|
||||
@ -673,54 +682,127 @@ init_interposition_intf ()
|
||||
|
||||
TprintfT (DBG_LT2, "init_interposition_intf() using RTLD_%s\n",
|
||||
(dlflag == RTLD_DEFAULT) ? "DEFAULT" : "NEXT");
|
||||
TprintfT (DBG_LT2, "@%p __real_setitimer\n", __real_setitimer);
|
||||
|
||||
__real_sigaction = dlsym (dlflag, SYS_SIGACTION_NAME);
|
||||
TprintfT (DBG_LT2, "@%p __real_sigaction\n", __real_sigaction);
|
||||
__real_sigaction = dlsym (dlflag, "sigaction");
|
||||
|
||||
/* also explicitly get libc.so/setitimer (as a backup) */
|
||||
__real_libc_setitimer = dlsym (handle, SYS_SETITIMER_NAME);
|
||||
TprintfT (DBG_LT2, "@%p __real_libc_setitimer\n", __real_libc_setitimer);
|
||||
__real_libc_setitimer = dlsym (handle, "setitimer");
|
||||
|
||||
__real_sigprocmask = dlsym (dlflag, SYS_SIGPROCMASK_NAME);
|
||||
TprintfT (DBG_LT2, "@%p __real_sigprocmask\n", __real_sigprocmask);
|
||||
__real_sigprocmask = dlsym (dlflag, "sigprocmask");
|
||||
__real_thr_sigsetmask = dlsym (dlflag, "thr_sigsetmask");
|
||||
|
||||
__real_thr_sigsetmask = dlsym (dlflag, SYS_THR_SIGSETMASK);
|
||||
TprintfT (DBG_LT2, "@%p __real_thr_sigsetmask\n", __real_thr_sigsetmask);
|
||||
__real_pthread_sigmask_2_32 = dlvsym (dlflag, "pthread_sigmask", "GLIBC_2.32");
|
||||
__real_pthread_sigmask_2_17 = dlvsym (dlflag, "pthread_sigmask", "GLIBC_2.17");
|
||||
__real_pthread_sigmask_2_2_5 = dlvsym (dlflag, "pthread_sigmask", "GLIBC_2.2.5");
|
||||
__real_pthread_sigmask_2_0 = dlvsym (dlflag, "pthread_sigmask", "GLIBC_2.0");
|
||||
__real_pthread_sigmask = dlsym (dlflag, "pthread_sigmask");
|
||||
|
||||
__real_pthread_sigmask = dlsym (dlflag, SYS_PTHREAD_SIGMASK);
|
||||
TprintfT (DBG_LT2, "@%p __real_pthread_sigmask\n", __real_pthread_sigmask);
|
||||
|
||||
#if ARCH(Aarch64)
|
||||
__real_pthread_create = dlvsym (dlflag, "pthread_create", SYS_PTHREAD_CREATE_VERSION);
|
||||
__real_timer_create = dlsym (dlflag, "timer_create");
|
||||
__real_timer_settime = dlsym (dlflag, "timer_settime");
|
||||
__real_timer_delete = dlsym (dlflag, "timer_delete");
|
||||
__real_timer_gettime = dlsym (dlflag, "timer_gettime");
|
||||
#else
|
||||
__real_pthread_create = dlvsym (dlflag, "pthread_create", SYS_PTHREAD_CREATE_VERSION);
|
||||
TprintfT (DBG_LT2, "[%s] @%p __real_pthread_create\n", SYS_PTHREAD_CREATE_VERSION, __real_pthread_create);
|
||||
__real_timer_create = dlvsym (dlflag, "timer_create", SYS_TIMER_X_VERSION);
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() [%s] @0x%p __real_timer_create\n", SYS_TIMER_X_VERSION, __real_timer_create);
|
||||
__real_timer_settime = dlvsym (dlflag, "timer_settime", SYS_TIMER_X_VERSION);
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() [%s] @0x%p __real_timer_settime\n", SYS_TIMER_X_VERSION, __real_timer_settime);
|
||||
__real_timer_delete = dlvsym (dlflag, "timer_delete", SYS_TIMER_X_VERSION);
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() [%s] @0x%p __real_timer_delete\n", SYS_TIMER_X_VERSION, __real_timer_delete);
|
||||
__real_timer_gettime = dlvsym (dlflag, "timer_gettime", SYS_TIMER_X_VERSION);
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() [%s] @0x%p __real_timer_gettime\n", SYS_TIMER_X_VERSION, __real_timer_gettime);
|
||||
__real_clone = dlsym (dlflag, "clone");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_clone\n", __real_clone);
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
__real_pthread_create_2_1 = __real_pthread_create;
|
||||
__real_pthread_create_2_34 = dlvsym (dlflag, "pthread_create", "GLIBC_2.34");
|
||||
__real_pthread_create_2_17 = dlvsym (dlflag, "pthread_create", "GLIBC_2.17");
|
||||
__real_pthread_create_2_2_5 = dlvsym (dlflag, "pthread_create", "GLIBC_2.2.5");
|
||||
__real_pthread_create_2_1 = dlvsym (dlflag, "pthread_create", "GLIBC_2.1");
|
||||
__real_pthread_create_2_0 = dlvsym (dlflag, "pthread_create", "GLIBC_2.0");
|
||||
#elif ARCH(Intel) && WSIZE(64)
|
||||
__real_timer_create_2_3_3 = __real_timer_create;
|
||||
if (__real_pthread_create_2_34)
|
||||
__real_pthread_create = __real_pthread_create_2_34;
|
||||
else if (__real_pthread_create_2_17)
|
||||
__real_pthread_create = __real_pthread_create_2_17;
|
||||
else if (__real_pthread_create_2_2_5)
|
||||
__real_pthread_create = __real_pthread_create_2_2_5;
|
||||
else if (__real_pthread_create_2_1)
|
||||
__real_pthread_create = __real_pthread_create_2_1;
|
||||
else if (__real_pthread_create_2_0)
|
||||
__real_pthread_create = __real_pthread_create_2_0;
|
||||
else
|
||||
__real_pthread_create = dlsym (dlflag, "pthread_create");
|
||||
|
||||
__real_timer_create_2_34 = dlvsym (dlflag, "timer_create", "GLIBC_2.34");
|
||||
__real_timer_create_2_17 = dlvsym (dlflag, "timer_create", "GLIBC_2.17");
|
||||
__real_timer_create_2_3_3 = dlvsym (dlflag, "timer_create", "GLIBC_2.3.3");
|
||||
__real_timer_create_2_2_5 = dlvsym (dlflag, "timer_create", "GLIBC_2.2.5");
|
||||
#elif ARCH(SPARC) && WSIZE(64)
|
||||
__real_timer_create_2_3_3 = __real_timer_create;
|
||||
__real_timer_create_2_2 = dlvsym (dlflag, "timer_create", "GLIBC_2.2");
|
||||
#endif /* ARCH() && SIZE() */
|
||||
#endif
|
||||
if (__real_timer_create_2_34)
|
||||
__real_timer_create = __real_timer_create_2_34;
|
||||
else if (__real_timer_create_2_17)
|
||||
__real_timer_create = __real_timer_create_2_17;
|
||||
else if (__real_timer_create_2_3_3)
|
||||
__real_timer_create = __real_timer_create_2_3_3;
|
||||
else if (__real_timer_create_2_2_5)
|
||||
__real_timer_create = __real_timer_create_2_2_5;
|
||||
else if (__real_timer_create_2_2)
|
||||
__real_timer_create = __real_timer_create_2_2;
|
||||
else
|
||||
__real_timer_create = dlsym (dlflag, "timer_create");
|
||||
|
||||
void *t;
|
||||
if ((t = dlvsym (dlflag, "timer_settime", "GLIBC_2.34")) != NULL)
|
||||
__real_timer_settime = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_settime", "GLIBC_2.17")) != NULL)
|
||||
__real_timer_settime = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_settime", "GLIBC_2.3.3")) != NULL)
|
||||
__real_timer_settime = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_settime", "GLIBC_2.2.5")) != NULL)
|
||||
__real_timer_settime = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_settime", "GLIBC_2.0")) != NULL)
|
||||
__real_timer_settime = t;
|
||||
else
|
||||
__real_timer_settime = dlsym (dlflag, "timer_settime");
|
||||
|
||||
if ((t = dlvsym (dlflag, "timer_delete", "GLIBC_2.34")) != NULL)
|
||||
__real_timer_delete = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_delete", "GLIBC_2.17")) != NULL)
|
||||
__real_timer_delete = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_delete", "GLIBC_2.3.3")) != NULL)
|
||||
__real_timer_delete = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_delete", "GLIBC_2.2.5")) != NULL)
|
||||
__real_timer_delete = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_delete", "GLIBC_2.2")) != NULL)
|
||||
__real_timer_delete = t;
|
||||
else
|
||||
__real_timer_delete = dlsym (dlflag, "timer_delete");
|
||||
|
||||
if ((t = dlvsym (dlflag, "timer_gettime", "GLIBC_2.34")) != NULL)
|
||||
__real_timer_gettime = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_gettime", "GLIBC_2.17")) != NULL)
|
||||
__real_timer_gettime = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_gettime", "GLIBC_2.3.3")) != NULL)
|
||||
__real_timer_gettime = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_gettime", "GLIBC_2.2.5")) != NULL)
|
||||
__real_timer_gettime = t;
|
||||
else if ((t = dlvsym (dlflag, "timer_gettime", "GLIBC_2.0")) != NULL)
|
||||
__real_timer_gettime = t;
|
||||
else
|
||||
__real_timer_gettime = dlsym (dlflag, "timer_gettime");
|
||||
|
||||
__real_clone = dlsym (dlflag, "clone");
|
||||
|
||||
#define PR_FUNC(f) TprintfT (DBG_LT2, " dispetcher.c: " #f ": @%p\n", f)
|
||||
PR_FUNC (__real_clone);
|
||||
PR_FUNC (__real_libc_setitimer);
|
||||
PR_FUNC (__real_pthread_create);
|
||||
PR_FUNC (__real_pthread_create_2_0);
|
||||
PR_FUNC (__real_pthread_create_2_1);
|
||||
PR_FUNC (__real_pthread_create_2_17);
|
||||
PR_FUNC (__real_pthread_create_2_2_5);
|
||||
PR_FUNC (__real_pthread_create_2_34);
|
||||
PR_FUNC (__real_pthread_sigmask);
|
||||
PR_FUNC (__real_pthread_sigmask_2_0);
|
||||
PR_FUNC (__real_pthread_sigmask_2_2_5);
|
||||
PR_FUNC (__real_pthread_sigmask_2_17);
|
||||
PR_FUNC (__real_pthread_sigmask_2_32);
|
||||
PR_FUNC (__real_setitimer);
|
||||
PR_FUNC (__real_sigaction);
|
||||
PR_FUNC (__real_sigprocmask);
|
||||
PR_FUNC (__real_thr_sigsetmask);
|
||||
PR_FUNC (__real_timer_create);
|
||||
PR_FUNC (__real_timer_create_2_17);
|
||||
PR_FUNC (__real_timer_create_2_2);
|
||||
PR_FUNC (__real_timer_create_2_2_5);
|
||||
PR_FUNC (__real_timer_create_2_3_3);
|
||||
PR_FUNC (__real_timer_create_2_34);
|
||||
PR_FUNC (__real_timer_delete);
|
||||
PR_FUNC (__real_timer_gettime);
|
||||
PR_FUNC (__real_timer_settime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -817,88 +899,44 @@ sigset (int sig, sighandler_t handler)
|
||||
/*------------------------------------------------------------- timer_create */
|
||||
|
||||
// map interposed symbol versions
|
||||
#if WSIZE(64)
|
||||
#if ARCH(SPARC) || ARCH(Intel)
|
||||
static int
|
||||
__collector_timer_create_symver (int(real_timer_create) (), clockid_t clockid, struct sigevent *sevp,
|
||||
timer_t *timerid);
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_timer_create_2_3_3, timer_create@GLIBC_2.3.3)
|
||||
int
|
||||
__collector_timer_create_2_3_3 (clockid_t clockid, struct sigevent *sevp,
|
||||
timer_t *timerid)
|
||||
gprofng_timer_create (int (real_func) (), clockid_t clockid,
|
||||
struct sigevent *sevp, timer_t *timerid)
|
||||
{
|
||||
if (NULL_PTR (timer_create))
|
||||
init_interposition_intf ();
|
||||
TprintfT (DBG_LTT, "dispatcher: GLIBC: __collector_timer_create_2_3_3@%p\n", CALL_REAL (timer_create_2_3_3));
|
||||
return __collector_timer_create_symver (CALL_REAL (timer_create_2_3_3), clockid, sevp, timerid);
|
||||
}
|
||||
#endif /* ARCH(SPARC) || ARCH(Intel)*/
|
||||
|
||||
#if ARCH(SPARC)
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_timer_create_2_2, timer_create@GLIBC_2.2)
|
||||
int
|
||||
__collector_timer_create_2_2 (clockid_t clockid, struct sigevent *sevp,
|
||||
timer_t *timerid)
|
||||
{
|
||||
if (NULL_PTR (timer_create))
|
||||
init_interposition_intf ();
|
||||
TprintfT (DBG_LTT, "dispatcher: GLIBC: __collector_timer_create_2_2@%p\n", CALL_REAL (timer_create_2_2));
|
||||
return __collector_timer_create_symver (CALL_REAL (timer_create_2_2), clockid, sevp, timerid);
|
||||
}
|
||||
|
||||
#elif ARCH(Intel)
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_timer_create_2_2_5, timer_create@GLIBC_2.2.5)
|
||||
int
|
||||
__collector_timer_create_2_2_5 (clockid_t clockid, struct sigevent *sevp,
|
||||
timer_t *timerid)
|
||||
{
|
||||
if (NULL_PTR (timer_create))
|
||||
init_interposition_intf ();
|
||||
TprintfT (DBG_LTT, "dispatcher: GLIBC: __collector_timer_create_2_2_5@%p\n", CALL_REAL (timer_create_2_2_5));
|
||||
return __collector_timer_create_symver (CALL_REAL (timer_create_2_2_5), clockid, sevp, timerid);
|
||||
}
|
||||
#endif /* ARCH() */
|
||||
#endif /* WSIZE(64) */
|
||||
|
||||
#if ARCH(Aarch64) || (ARCH(Intel) && WSIZE(32))
|
||||
int timer_create (clockid_t clockid, struct sigevent *sevp, timer_t *timerid)
|
||||
#else
|
||||
static int
|
||||
__collector_timer_create_symver (int(real_timer_create) (), clockid_t clockid,
|
||||
struct sigevent *sevp, timer_t *timerid)
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (NULL_PTR (timer_create))
|
||||
init_interposition_intf ();
|
||||
|
||||
/* collector reserves SIGPROF
|
||||
*/
|
||||
if (sevp == NULL || sevp->sigev_notify != SIGEV_SIGNAL
|
||||
|| sevp->sigev_signo != SIGPROF)
|
||||
// collector reserves SIGPROF
|
||||
if (sevp == NULL || sevp->sigev_notify != SIGEV_SIGNAL ||
|
||||
sevp->sigev_signo != SIGPROF)
|
||||
{
|
||||
#if ARCH(Aarch64) || (ARCH(Intel) && WSIZE(32))
|
||||
ret = CALL_REAL (timer_create)(clockid, sevp, timerid);
|
||||
#else
|
||||
ret = (real_timer_create) (clockid, sevp, timerid);
|
||||
#endif
|
||||
TprintfT (DBG_LT2, "Real timer_create(%d) returned %d\n",
|
||||
clockid, ret);
|
||||
int ret = real_func (clockid, sevp, timerid);
|
||||
TprintfT (DBG_LT2, "timer_create @%p (%d) ret=%d\n", real_func,
|
||||
(int) clockid, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* log that application's timer_create request is overridden */
|
||||
(void) __collector_log_write ("<event kind=\"%s\" id=\"%d\">%d</event>\n",
|
||||
SP_JCMD_CWARN, COL_WARN_ITMROVR, -1);
|
||||
ret = -1;
|
||||
errno = EBUSY;
|
||||
TprintfT (DBG_LT2, "timer_create() returning %d\n", ret);
|
||||
return ret;
|
||||
TprintfT (DBG_LT2, "timer_create @%p (%d) ret=%d\n", real_func,
|
||||
(int) clockid, -1); \
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define DCL_TIMER_CREATE(dcl_f, real_f) \
|
||||
int dcl_f (clockid_t clockid, struct sigevent *sevp, timer_t *timerid) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_interposition_intf (); \
|
||||
return gprofng_timer_create (real_f, clockid, sevp, timerid); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_TIMER_CREATE, timer_create_2_34, timer_create@GLIBC_2.34)
|
||||
DCL_FUNC_VER (DCL_TIMER_CREATE, timer_create_2_17, timer_create@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_TIMER_CREATE, timer_create_2_3_3, timer_create@GLIBC_2.3.3)
|
||||
DCL_FUNC_VER (DCL_TIMER_CREATE, timer_create_2_2_5, timer_create@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_TIMER_CREATE, timer_create_2_2, timer_create@GLIBC_2.2)
|
||||
DCL_TIMER_CREATE (timer_create, CALL_REAL (timer_create))
|
||||
|
||||
/*------------------------------------------------------------- setitimer */
|
||||
int
|
||||
_setitimer (int which, const struct itimerval *nval,
|
||||
@ -995,26 +1033,42 @@ __collector_thr_sigsetmask (int how, const sigset_t* iset, sigset_t* oset)
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------- pthread_sigmask */
|
||||
// map interposed symbol versions
|
||||
|
||||
int
|
||||
pthread_sigmask (int how, const sigset_t* iset, sigset_t* oset)
|
||||
static int
|
||||
gprofng_pthread_sigmask (int (real_func) (),
|
||||
int how, const sigset_t *iset, sigset_t* oset)
|
||||
{
|
||||
if (NULL_PTR (pthread_sigmask))
|
||||
init_interposition_intf ();
|
||||
TprintfT (DBG_LT1, "__collector_pthread_sigmask(%d) interposing\n", how);
|
||||
sigset_t lsigset;
|
||||
sigset_t* lset = NULL;
|
||||
if (iset)
|
||||
{
|
||||
lsigset = *iset;
|
||||
lset = &lsigset;
|
||||
if ((how == SIG_BLOCK) || (how == SIG_SETMASK))
|
||||
protect_profiling_signals (lset);
|
||||
if (how == SIG_BLOCK || how == SIG_SETMASK)
|
||||
protect_profiling_signals (lset);
|
||||
}
|
||||
int ret = CALL_REAL (pthread_sigmask)(how, lset, oset);
|
||||
TprintfT (DBG_LT1, "__collector_pthread_sigmask(%d) returning %d\n", how, ret);
|
||||
int ret = (real_func) (how, lset, oset);
|
||||
TprintfT (DBG_LT1, "real_pthread_sigmask @%p (%d) ret=%d\n",
|
||||
real_func, how, ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#define DCL_PTHREAD_SIGMASK(dcl_f, real_f) \
|
||||
int dcl_f (int how, const sigset_t *iset, sigset_t* oset) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_interposition_intf (); \
|
||||
return gprofng_pthread_sigmask (real_f, how, iset, oset); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_PTHREAD_SIGMASK, pthread_sigmask_2_32, pthread_sigmask@GLIBC_2.32)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_SIGMASK, pthread_sigmask_2_17, pthread_sigmask@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_SIGMASK, pthread_sigmask_2_2_5, pthread_sigmask@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_SIGMASK, pthread_sigmask_2_0, pthread_sigmask@GLIBC_2.0)
|
||||
DCL_PTHREAD_SIGMASK (pthread_sigmask, CALL_REAL(pthread_sigmask))
|
||||
|
||||
/*----------------------------------------------------------- pthread_create */
|
||||
typedef struct _CollectorArgs
|
||||
{
|
||||
@ -1075,94 +1129,47 @@ collector_root (void *cargs)
|
||||
}
|
||||
|
||||
// map interposed symbol versions
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
|
||||
static int
|
||||
__collector_pthread_create_symver (int(real_pthread_create) (),
|
||||
pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*func)(void*),
|
||||
void *arg);
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_create_2_1, pthread_create@GLIBC_2.1)
|
||||
int
|
||||
__collector_pthread_create_2_1 (pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*func)(void*),
|
||||
void *arg)
|
||||
gprofng_pthread_create (int (real_func) (), pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*func)(void*), void *arg)
|
||||
{
|
||||
if (NULL_PTR (pthread_create))
|
||||
init_interposition_intf ();
|
||||
TprintfT (DBG_LTT, "dispatcher: GLIBC: __collector_pthread_create_2_1@%p\n", CALL_REAL (pthread_create_2_1));
|
||||
return __collector_pthread_create_symver (CALL_REAL (pthread_create_2_1), thread, attr, func, arg);
|
||||
}
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_create_2_0, pthread_create@GLIBC_2.0)
|
||||
int
|
||||
__collector_pthread_create_2_0 (pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*func)(void*),
|
||||
void *arg)
|
||||
{
|
||||
if (NULL_PTR (pthread_create))
|
||||
init_interposition_intf ();
|
||||
TprintfT (DBG_LTT, "dispatcher: GLIBC: __collector_pthread_create_2_0@%p\n", CALL_REAL (pthread_create_2_0));
|
||||
return __collector_pthread_create_symver (CALL_REAL (pthread_create_2_0), thread, attr, func, arg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
static int
|
||||
__collector_pthread_create_symver (int(real_pthread_create) (),
|
||||
pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*func)(void*),
|
||||
void *arg)
|
||||
#else
|
||||
int
|
||||
pthread_create (pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*func)(void*), void *arg)
|
||||
#endif
|
||||
{
|
||||
if (NULL_PTR (pthread_create))
|
||||
init_interposition_intf ();
|
||||
|
||||
TprintfT (DBG_LT1, "pthread_create interposition called\n");
|
||||
|
||||
TprintfT (DBG_LTT, "gprofng_pthread_create @%p\n", real_func);
|
||||
if (dispatch_mode != DISPATCH_ON)
|
||||
{
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
return (real_pthread_create) (thread, attr, func, arg);
|
||||
#else
|
||||
return CALL_REAL (pthread_create)(thread, attr, func, arg);
|
||||
#endif
|
||||
}
|
||||
CollectorArgs *cargs = __collector_allocCSize (__collector_heap, sizeof (CollectorArgs), 1);
|
||||
|
||||
return (real_func) (thread, attr, func, arg);
|
||||
CollectorArgs *cargs = __collector_allocCSize (__collector_heap,
|
||||
sizeof (CollectorArgs), 1);
|
||||
if (cargs == NULL)
|
||||
{
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
return (real_pthread_create) (thread, attr, func, arg);
|
||||
#else
|
||||
return CALL_REAL (pthread_create)(thread, attr, func, arg);
|
||||
#endif
|
||||
}
|
||||
return (real_func) (thread, attr, func, arg);
|
||||
cargs->func = func;
|
||||
cargs->arg = arg;
|
||||
cargs->stack = NULL;
|
||||
cargs->isPthread = 1;
|
||||
int ret = -1;
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
ret = (real_pthread_create) (thread, attr, &collector_root, cargs);
|
||||
#else
|
||||
ret = CALL_REAL (pthread_create)(thread, attr, &collector_root, cargs);
|
||||
#endif
|
||||
int ret = (real_func) (thread, attr, &collector_root, cargs);
|
||||
if (ret)
|
||||
__collector_freeCSize (__collector_heap, cargs, sizeof (CollectorArgs));
|
||||
TprintfT (DBG_LT1, "pthread_create returning %d\n", ret);
|
||||
TprintfT (DBG_LT1, "gprofng_pthread_create @%p returns %d\n", real_func, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#define DCL_PTHREAD_CREATE(dcl_f, real_f) \
|
||||
int dcl_f (pthread_t *thread, const pthread_attr_t *attr, \
|
||||
void *(*func)(void*), void *arg) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_interposition_intf (); \
|
||||
return gprofng_pthread_create (real_f, thread, attr, func, arg); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_PTHREAD_CREATE, pthread_create_2_34, pthread_create@GLIBC_2.34)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_CREATE, pthread_create_2_17, pthread_create@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_CREATE, pthread_create_2_2_5, pthread_create@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_CREATE, pthread_create_2_1, pthread_create@GLIBC_2.1)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_CREATE, pthread_create_2_0, pthread_create@GLIBC_2.0)
|
||||
DCL_PTHREAD_CREATE (pthread_create, CALL_REAL (pthread_create))
|
||||
|
||||
int
|
||||
__collector_ext_clone_pthread (int (*fn)(void *), void *child_stack, int flags, void *arg,
|
||||
va_list va /* pid_t *ptid, struct user_desc *tls, pid_t *" ctid" */)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -40,12 +40,6 @@
|
||||
#include "memmgr.h" // __collector_allocCSize, __collector_freeCSize
|
||||
#include "tsd.h"
|
||||
|
||||
/* TprintfT(<level>,...) definitions. Adjust per module as needed */
|
||||
#define DBG_LT0 0 // for high-level configuration, unexpected errors/warnings
|
||||
#define DBG_LT1 1 // for configuration details, warnings
|
||||
#define DBG_LT2 2
|
||||
#define DBG_LT3 3
|
||||
|
||||
/*
|
||||
* This file is intended for collector's own implementation of
|
||||
* various routines to avoid interaction with libc and other
|
||||
@ -1456,54 +1450,53 @@ __collector_util_init ()
|
||||
/* don't treat this as fatal, so that S10 could work */
|
||||
}
|
||||
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
ptr = dlvsym (libc, "fopen", "GLIBC_2.1");
|
||||
if (ptr)
|
||||
__collector_util_funcs.fopen = (FILE * (*)())ptr;
|
||||
if ((ptr = dlvsym (libc, "fopen", "GLIBC_2.17")) != NULL)
|
||||
__collector_util_funcs.fopen = ptr;
|
||||
else if ((ptr = dlvsym (libc, "fopen", "GLIBC_2.2.5")) != NULL)
|
||||
__collector_util_funcs.fopen = ptr;
|
||||
else if ((ptr = dlvsym (libc, "fopen", "GLIBC_2.1")) != NULL)
|
||||
__collector_util_funcs.fopen = ptr;
|
||||
else if ((ptr = dlvsym (libc, "fopen", "GLIBC_2.0")) != NULL)
|
||||
__collector_util_funcs.fopen = ptr;
|
||||
else
|
||||
ptr = dlsym (libc, "fopen");
|
||||
if (__collector_util_funcs.fopen == NULL)
|
||||
{
|
||||
Tprintf (DBG_LT0, "libcol_util: WARNING: dlvsym for %s@%s failed. Using dlsym() instead.", "fopen", "GLIBC_2.1");
|
||||
#endif /* ARCH(Intel) && WSIZE(32) */
|
||||
ptr = dlsym (libc, "fopen");
|
||||
if (ptr)
|
||||
__collector_util_funcs.fopen = (FILE * (*)())ptr;
|
||||
else
|
||||
{
|
||||
CALL_UTIL (fprintf)(stderr, "collector_util_init COL_ERROR_UTIL_INIT fopen: %s\n", dlerror ());
|
||||
err = COL_ERROR_UTIL_INIT;
|
||||
}
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr = dlsym (libc, "popen");
|
||||
if (ptr)
|
||||
__collector_util_funcs.popen = (FILE * (*)())ptr;
|
||||
else
|
||||
{
|
||||
CALL_UTIL (fprintf)(stderr, "collector_util_init COL_ERROR_UTIL_INIT popen: %s\n", dlerror ());
|
||||
CALL_UTIL (fprintf)(stderr, "COL_ERROR_UTIL_INIT fopen: %s\n", dlerror ());
|
||||
err = COL_ERROR_UTIL_INIT;
|
||||
}
|
||||
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
ptr = dlvsym (libc, "fclose", "GLIBC_2.1");
|
||||
if (ptr)
|
||||
__collector_util_funcs.fclose = (int(*)())ptr;
|
||||
if ((ptr = dlvsym (libc, "popen", "GLIBC_2.17")) != NULL)
|
||||
__collector_util_funcs.popen = ptr;
|
||||
else if ((ptr = dlvsym (libc, "popen", "GLIBC_2.2.5")) != NULL)
|
||||
__collector_util_funcs.popen = ptr;
|
||||
else if ((ptr = dlvsym (libc, "popen", "GLIBC_2.1")) != NULL)
|
||||
__collector_util_funcs.popen = ptr;
|
||||
else if ((ptr = dlvsym (libc, "popen", "GLIBC_2.0")) != NULL)
|
||||
__collector_util_funcs.popen = ptr;
|
||||
else
|
||||
ptr = dlsym (libc, "popen");
|
||||
if (__collector_util_funcs.popen == NULL)
|
||||
{
|
||||
Tprintf (DBG_LT0, "libcol_util: WARNING: dlvsym for %s@%s failed. Using dlsym() instead.", "fclose", "GLIBC_2.1");
|
||||
#endif /* ARCH(Intel) && WSIZE(32) */
|
||||
ptr = dlsym (libc, "fclose");
|
||||
if (ptr)
|
||||
__collector_util_funcs.fclose = (int(*)())ptr;
|
||||
else
|
||||
{
|
||||
CALL_UTIL (fprintf)(stderr, "collector_util_init COL_ERROR_UTIL_INIT fclose: %s\n", dlerror ());
|
||||
err = COL_ERROR_UTIL_INIT;
|
||||
}
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
CALL_UTIL (fprintf)(stderr, "COL_ERROR_UTIL_INIT popen: %s\n", dlerror ());
|
||||
err = COL_ERROR_UTIL_INIT;
|
||||
}
|
||||
|
||||
if ((ptr = dlvsym (libc, "fclose", "GLIBC_2.17")) != NULL)
|
||||
__collector_util_funcs.fclose = ptr;
|
||||
else if ((ptr = dlvsym (libc, "fclose", "GLIBC_2.2.5")) != NULL)
|
||||
__collector_util_funcs.fclose = ptr;
|
||||
else if ((ptr = dlvsym (libc, "fclose", "GLIBC_2.1")) != NULL)
|
||||
__collector_util_funcs.fclose = ptr;
|
||||
else if ((ptr = dlvsym (libc, "fclose", "GLIBC_2.0")) != NULL)
|
||||
__collector_util_funcs.fclose = ptr;
|
||||
else
|
||||
ptr = dlsym (libc, "fclose");
|
||||
if (__collector_util_funcs.fclose == NULL)
|
||||
{
|
||||
CALL_UTIL (fprintf)(stderr, "COL_ERROR_UTIL_INIT fclose: %s\n", dlerror ());
|
||||
err = COL_ERROR_UTIL_INIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr = dlsym (libc, "pclose");
|
||||
if (ptr)
|
||||
|
125
gprofng/libcollector/libgprofng.ver
Normal file
125
gprofng/libcollector/libgprofng.ver
Normal file
@ -0,0 +1,125 @@
|
||||
/* Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
Contributed by Oracle.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
GLIBC_2.0 {
|
||||
global:
|
||||
pthread_create;
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_sigmask;
|
||||
popen;
|
||||
};
|
||||
|
||||
GLIBC_2.1 {
|
||||
global:
|
||||
pthread_create;
|
||||
popen;
|
||||
} GLIBC_2.0;
|
||||
|
||||
GLIBC_2.2 {
|
||||
global:
|
||||
open64;
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
pread;
|
||||
pwrite;
|
||||
pwrite64;
|
||||
timer_create;
|
||||
fgetpos;
|
||||
fsetpos;
|
||||
fgetpos64;
|
||||
fsetpos64;
|
||||
} GLIBC_2.1;
|
||||
|
||||
GLIBC_2.2.5 {
|
||||
global:
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_sigmask;
|
||||
pthread_join;
|
||||
sem_wait;
|
||||
pthread_create;
|
||||
dlopen;
|
||||
popen;
|
||||
timer_create;
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
fopen;
|
||||
fclose;
|
||||
fdopen;
|
||||
fgetpos;
|
||||
fsetpos;
|
||||
} GLIBC_2.2 ;
|
||||
|
||||
GLIBC_2.3.2 {
|
||||
global:
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
} GLIBC_2.2.5;
|
||||
|
||||
GLIBC_2.3.3 {
|
||||
global:
|
||||
timer_create;
|
||||
} GLIBC_2.3.2;
|
||||
|
||||
GLIBC_2.15 {
|
||||
global:
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
} GLIBC_2.3.3;
|
||||
|
||||
GLIBC_2.17 {
|
||||
global:
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_sigmask;
|
||||
pthread_join;
|
||||
sem_wait;
|
||||
pthread_create;
|
||||
dlopen;
|
||||
popen;
|
||||
timer_create;
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
fopen;
|
||||
fclose;
|
||||
fdopen;
|
||||
fgetpos;
|
||||
fsetpos;
|
||||
} GLIBC_2.15;
|
||||
|
||||
GLIBC_2.32 {
|
||||
global:
|
||||
pthread_sigmask;
|
||||
} GLIBC_2.17;
|
||||
|
||||
GLIBC_2.34 {
|
||||
global:
|
||||
pthread_join;
|
||||
sem_wait;
|
||||
pthread_create;
|
||||
dlopen;
|
||||
timer_create;
|
||||
} GLIBC_2.32;
|
||||
|
@ -73,27 +73,15 @@ static int (*__real_grantpt) (int fd) = NULL;
|
||||
static char *(*__real_ptsname) (int fd) = NULL;
|
||||
static FILE *(*__real_popen) (const char *command, const char *type) = NULL;
|
||||
static int clone_linenum = 0;
|
||||
#if ARCH(Intel)
|
||||
#if WSIZE(32)
|
||||
static FILE *(*__real_popen_2_17) (const char *command, const char *type) = NULL;
|
||||
static FILE *(*__real_popen_2_2_5) (const char *command, const char *type) = NULL;
|
||||
static FILE *(*__real_popen_2_1) (const char *command, const char *type) = NULL;
|
||||
static FILE *(*__real_popen_2_0) (const char *command, const char *type) = NULL;
|
||||
static int (*__real_posix_spawn_2_15) (pid_t *pid, const char *path,
|
||||
|
||||
static int (*__real_posix_spawn_2_17) (pid_t *pid, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]) = NULL;
|
||||
static int (*__real_posix_spawn_2_2) (pid_t *pid, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]) = NULL;
|
||||
static int (*__real_posix_spawnp_2_15) (pid_t *pid, const char *file,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]) = NULL;
|
||||
static int (*__real_posix_spawnp_2_2) (pid_t *pid, const char *file,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]) = NULL;
|
||||
#elif WSIZE(64)
|
||||
static int (*__real_posix_spawn_2_15) (pid_t *pid, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
@ -102,6 +90,15 @@ static int (*__real_posix_spawn_2_2_5) (pid_t *pid, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]) = NULL;
|
||||
static int (*__real_posix_spawn_2_2) (pid_t *pid, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]) = NULL;
|
||||
|
||||
static int (*__real_posix_spawnp_2_17) (pid_t *pid, const char *file,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]) = NULL;
|
||||
static int (*__real_posix_spawnp_2_15) (pid_t *pid, const char *file,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
@ -110,8 +107,10 @@ static int (*__real_posix_spawnp_2_2_5) (pid_t *pid, const char *file,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]) = NULL;
|
||||
#endif /* WSIZE() */
|
||||
#endif /* ARCH(Intel) */
|
||||
static int (*__real_posix_spawnp_2_2) (pid_t *pid, const char *file,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]) = NULL;
|
||||
static int (*__real_system) (const char *command) = NULL;
|
||||
static int (*__real_posix_spawn) (pid_t *pid, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
@ -675,63 +674,87 @@ init_lineage_intf ()
|
||||
dlflag = RTLD_NEXT;
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() using RTLD_%s\n",
|
||||
dlflag == RTLD_DEFAULT ? "DEFAULT" : "NEXT");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_fork\n", __real_fork);
|
||||
__real_vfork = dlsym (dlflag, "vfork");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_vfork\n", __real_vfork);
|
||||
__real_execve = dlsym (dlflag, "execve");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_execve\n", __real_execve);
|
||||
__real_execvp = dlsym (dlflag, "execvp");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_execvp\n", __real_execvp);
|
||||
__real_execv = dlsym (dlflag, "execv");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_execv\n", __real_execv);
|
||||
__real_execle = dlsym (dlflag, "execle");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_execle\n", __real_execle);
|
||||
__real_execlp = dlsym (dlflag, "execlp");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_execlp\n", __real_execlp);
|
||||
__real_execl = dlsym (dlflag, "execl");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_execl\n", __real_execl);
|
||||
__real_clone = dlsym (dlflag, "clone");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_clone\n", __real_clone);
|
||||
__real_posix_spawn = dlsym (dlflag, "posix_spawn");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_posix_spawn\n",
|
||||
__real_posix_spawn);
|
||||
__real_posix_spawnp = dlsym (dlflag, "posix_spawnp");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_posix_spawnp\n",
|
||||
__real_posix_spawnp);
|
||||
__real_popen = dlvsym (dlflag, "popen", SYS_POPEN_VERSION);
|
||||
TprintfT (DBG_LT2, "init_lineage_intf()[%s] @0x%p __real_popen\n",
|
||||
SYS_POPEN_VERSION, __real_popen);
|
||||
#if ARCH(Intel)
|
||||
__real_posix_spawn_2_15 = dlvsym (dlflag, "posix_spawn", SYS_POSIX_SPAWN_VERSION);
|
||||
__real_posix_spawnp_2_15 = dlvsym (dlflag, "posix_spawnp", SYS_POSIX_SPAWN_VERSION);
|
||||
#if WSIZE(32)
|
||||
__real_popen_2_1 = __real_popen;
|
||||
|
||||
__real_popen_2_17 = dlvsym (dlflag, "popen", "GLIBC_2.17");
|
||||
__real_popen_2_2_5 = dlvsym (dlflag, "popen", "GLIBC_2.2.5");
|
||||
__real_popen_2_1 = dlvsym (dlflag, "popen", "GLIBC_2.1");
|
||||
__real_popen_2_0 = dlvsym (dlflag, "popen", "GLIBC_2.0");
|
||||
__real_posix_spawn_2_2 = dlvsym (dlflag, "posix_spawn", "GLIBC_2.2");
|
||||
__real_posix_spawnp_2_2 = dlvsym (dlflag, "posix_spawnp", "GLIBC_2.2");
|
||||
#elif WSIZE(64)
|
||||
if (__real_popen_2_17)
|
||||
__real_popen = __real_popen_2_17;
|
||||
else if (__real_popen_2_2_5)
|
||||
__real_popen = __real_popen_2_2_5;
|
||||
else if (__real_popen_2_1)
|
||||
__real_popen = __real_popen_2_1;
|
||||
else if (__real_popen_2_0)
|
||||
__real_popen = __real_popen_2_0;
|
||||
else
|
||||
__real_popen = dlsym (dlflag, "popen");
|
||||
|
||||
__real_posix_spawn_2_17 = dlvsym (dlflag, "posix_spawn", "GLIBC_2.17");
|
||||
__real_posix_spawn_2_15 = dlvsym (dlflag, "posix_spawn", "GLIBC_2.15");
|
||||
__real_posix_spawn_2_2_5 = dlvsym (dlflag, "posix_spawn", "GLIBC_2.2.5");
|
||||
__real_posix_spawn_2_2 = dlvsym (dlflag, "posix_spawn", "GLIBC_2.2");
|
||||
|
||||
__real_posix_spawnp_2_17 = dlvsym (dlflag, "posix_spawnp", "GLIBC_2.17");
|
||||
__real_posix_spawnp_2_15 = dlvsym (dlflag, "posix_spawnp", "GLIBC_2.15");
|
||||
__real_posix_spawnp_2_2_5 = dlvsym (dlflag, "posix_spawnp", "GLIBC_2.2.5");
|
||||
#endif /* WSIZE() */
|
||||
#endif /* ARCH(Intel) */
|
||||
__real_posix_spawnp_2_2 = dlvsym (dlflag, "posix_spawnp", "GLIBC_2.2");
|
||||
|
||||
__real_grantpt = dlsym (dlflag, "grantpt");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_grantpt\n", __real_grantpt);
|
||||
__real_ptsname = dlsym (dlflag, "ptsname");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_ptsname\n", __real_ptsname);
|
||||
__real_system = dlsym (dlflag, "system");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_system\n", __real_system);
|
||||
__real_setuid = dlsym (dlflag, "setuid");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_setuid\n", __real_setuid);
|
||||
__real_seteuid = dlsym (dlflag, "seteuid");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_seteuid\n", __real_seteuid);
|
||||
__real_setreuid = dlsym (dlflag, "setreuid");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_setreuid\n", __real_setreuid);
|
||||
__real_setgid = dlsym (dlflag, "setgid");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_setgid\n", __real_setgid);
|
||||
__real_setegid = dlsym (dlflag, "setegid");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_setegid\n", __real_setegid);
|
||||
__real_setregid = dlsym (dlflag, "setregid");
|
||||
TprintfT (DBG_LT2, "init_lineage_intf() @0x%p __real_setregid\n", __real_setregid);
|
||||
|
||||
#define PR_FUNC(f) TprintfT (DBG_LT2, "linetrace.c: " #f ": @%p\n", f)
|
||||
PR_FUNC (__real_fork);
|
||||
PR_FUNC (__real_vfork);
|
||||
PR_FUNC (__real_execve);
|
||||
PR_FUNC (__real_execvp);
|
||||
PR_FUNC (__real_execv);
|
||||
PR_FUNC (__real_execle);
|
||||
PR_FUNC (__real_execlp);
|
||||
PR_FUNC (__real_execl);
|
||||
PR_FUNC (__real_clone);
|
||||
PR_FUNC (__real_grantpt);
|
||||
PR_FUNC (__real_ptsname);
|
||||
PR_FUNC (__real_popen);
|
||||
PR_FUNC (__real_popen_2_17);
|
||||
PR_FUNC (__real_popen_2_2_5);
|
||||
PR_FUNC (__real_popen_2_1);
|
||||
PR_FUNC (__real_popen_2_0);
|
||||
PR_FUNC (__real_posix_spawn_2_17);
|
||||
PR_FUNC (__real_posix_spawn_2_15);
|
||||
PR_FUNC (__real_posix_spawn_2_2_5);
|
||||
PR_FUNC (__real_posix_spawn_2_2);
|
||||
PR_FUNC (__real_posix_spawnp_2_17);
|
||||
PR_FUNC (__real_posix_spawnp_2_15);
|
||||
PR_FUNC (__real_posix_spawnp_2_2_5);
|
||||
PR_FUNC (__real_posix_spawnp_2_2);
|
||||
PR_FUNC (__real_system);
|
||||
PR_FUNC (__real_posix_spawn);
|
||||
PR_FUNC (__real_posix_spawnp);
|
||||
PR_FUNC (__real_setuid);
|
||||
PR_FUNC (__real_seteuid);
|
||||
PR_FUNC (__real_setreuid);
|
||||
PR_FUNC (__real_setgid);
|
||||
PR_FUNC (__real_setegid);
|
||||
PR_FUNC (__real_setregid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1365,226 +1388,120 @@ __collector_execl (const char* path, const char *arg0, ...)
|
||||
#include <spawn.h>
|
||||
|
||||
/*-------------------------------------------------------- posix_spawn */
|
||||
#if ARCH(Intel)
|
||||
// map interposed symbol versions
|
||||
static int
|
||||
__collector_posix_spawn_symver (int(real_posix_spawn) (),
|
||||
pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]);
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_posix_spawn_2_15, posix_spawn@GLIBC_2.15)
|
||||
int
|
||||
__collector_posix_spawn_2_15 (pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[])
|
||||
{
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_posix_spawn_2_15@%p(path=%s, argv[0]=%s, env[0]=%s)\n",
|
||||
CALL_REAL (posix_spawn_2_15), path ? path : "NULL", argv ? (argv[0] ? argv[0] : "NULL") : "NULL", envp ? (envp[0] ? envp[0] : "NULL") : "NULL");
|
||||
if (NULL_PTR (posix_spawn))
|
||||
init_lineage_intf ();
|
||||
return __collector_posix_spawn_symver (CALL_REAL (posix_spawn_2_15), pidp,
|
||||
path, file_actions, attrp, argv, envp);
|
||||
}
|
||||
|
||||
#if WSIZE(32)
|
||||
SYMVER_ATTRIBUTE (__collector_posix_spawn_2_2, posix_spawn@GLIBC_2.2)
|
||||
int
|
||||
__collector_posix_spawn_2_2 (pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[])
|
||||
{
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_posix_spawn_2_2@%p(path=%s, argv[0]=%s, env[0]=%s)\n",
|
||||
CALL_REAL (posix_spawn_2_2), path ? path : "NULL", argv ? (argv[0] ? argv[0] : "NULL") : "NULL", envp ? (envp[0] ? envp[0] : "NULL") : "NULL");
|
||||
if (NULL_PTR (posix_spawn))
|
||||
init_lineage_intf ();
|
||||
return __collector_posix_spawn_symver (CALL_REAL (posix_spawn_2_2), pidp,
|
||||
path, file_actions, attrp, argv, envp);
|
||||
}
|
||||
|
||||
#else /* ^WSIZE(32) */
|
||||
SYMVER_ATTRIBUTE (__collector_posix_spawn_2_2_5, posix_spawn@GLIBC_2.2.5)
|
||||
int
|
||||
__collector_posix_spawn_2_2_5 (pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[])
|
||||
{
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_posix_spawn_2_2_5@%p(path=%s, argv[0]=%s, env[0]=%s)\n",
|
||||
CALL_REAL (posix_spawn_2_2_5), path ? path : "NULL", argv ? (argv[0] ? argv[0] : "NULL") : "NULL", envp ? (envp[0] ? envp[0] : "NULL") : "NULL");
|
||||
if (NULL_PTR (posix_spawn))
|
||||
init_lineage_intf ();
|
||||
return __collector_posix_spawn_symver (CALL_REAL (posix_spawn_2_2_5), pidp,
|
||||
path, file_actions, attrp, argv, envp);
|
||||
}
|
||||
#endif /* ^WSIZE(32) */
|
||||
|
||||
static int
|
||||
__collector_posix_spawn_symver (int(real_posix_spawn) (),
|
||||
#else /* ^ARCH(Intel) */
|
||||
int
|
||||
__collector_posix_spawn (
|
||||
#endif /* ARCH() */
|
||||
pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[])
|
||||
gprofng_posix_spawn (int(real_posix_spawn) (),
|
||||
pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[])
|
||||
{
|
||||
int ret;
|
||||
static char **coll_env = NULL; /* environment for collection */
|
||||
if (NULL_PTR (posix_spawn))
|
||||
init_lineage_intf ();
|
||||
if (NULL_PTR (posix_spawn))
|
||||
if (real_posix_spawn == NULL)
|
||||
{
|
||||
TprintfT (DBG_LT0, "__collector_posix_spawn(path=%s) interposing: ERROR, posix_spawn() not found by dlsym\n",
|
||||
TprintfT (DBG_LT0, "gprofng_posix_spawn (path=%s) interposin ERROR, posix_spawn() not found by dlsym\n",
|
||||
path ? path : "NULL");
|
||||
return -1; /* probably should set errno */
|
||||
}
|
||||
int * guard = NULL;
|
||||
int combo_flag = (line_mode == LM_TRACK_LINEAGE) ? ((CHCK_REENTRANCE (guard)) ? 1 : 0) : 0;
|
||||
TprintfT (DBG_LT0, "__collector_posix_spawn(path=%s, argv[0]=%s, env[0]=%s) interposing: line_mode=%d combo=%d\n",
|
||||
path ? path : "NULL", argv ? (argv[0] ? argv[0] : "NULL") : "NULL", envp ? (envp[0] ? envp[0] : "NULL") : "NULL", line_mode, combo_flag);
|
||||
int *guard = NULL;
|
||||
int combo_flag = (line_mode == LM_TRACK_LINEAGE &&
|
||||
CHCK_REENTRANCE (guard)) ? 1 : 0;
|
||||
TprintfT (DBG_LT0, "gprofng_posix_spawn @%p (%s, argv[0]=%s, env[0]=%s)"
|
||||
"line_mode=%d combo=%d\n", (real_posix_spawn), path ? path : "NULL",
|
||||
(argv && argv[0]) ? argv[0] : "NULL",
|
||||
(envp && envp[0]) ? envp[0] : "NULL", line_mode, combo_flag);
|
||||
if (line_mode == LM_CLOSED) /* ensure collection environment is sanitised */
|
||||
__collector_env_unset ((char**) envp);
|
||||
|
||||
if ((line_mode != LM_TRACK_LINEAGE) || combo_flag)
|
||||
{
|
||||
#if ARCH(Intel)
|
||||
return (real_posix_spawn) (pidp, path, file_actions, attrp, argv, envp);
|
||||
#else
|
||||
return CALL_REAL (posix_spawn)(pidp, path, file_actions, attrp, argv, envp);
|
||||
#endif
|
||||
}
|
||||
if (line_mode != LM_TRACK_LINEAGE || combo_flag)
|
||||
return (real_posix_spawn) (pidp, path, file_actions, attrp, argv, envp);
|
||||
int following_exec = 0;
|
||||
coll_env = linetrace_ext_exec_prologue ("posix_spawn", path, argv, envp, &following_exec);
|
||||
TprintfT (DBG_LT0, "__collector_posix_spawn(): coll_env=0x%p\n", coll_env);
|
||||
__collector_env_printall ("__collector_posix_spawn", coll_env);
|
||||
coll_env = linetrace_ext_exec_prologue ("posix_spawn", path, argv, envp,
|
||||
&following_exec);
|
||||
__collector_env_printall ("gprofng_posix_spawn", coll_env);
|
||||
PUSH_REENTRANCE (guard);
|
||||
#if ARCH(Intel)
|
||||
ret = (real_posix_spawn) (pidp, path, file_actions, attrp, argv, coll_env);
|
||||
#else
|
||||
ret = CALL_REAL (posix_spawn)(pidp, path, file_actions, attrp, argv, coll_env);
|
||||
#endif
|
||||
ret = real_posix_spawn (pidp, path, file_actions, attrp, argv, coll_env);
|
||||
POP_REENTRANCE (guard);
|
||||
linetrace_ext_exec_epilogue ("posix_spawn", envp, ret, &following_exec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DCL_POSIX_SPAWN(dcl_f, real_f) \
|
||||
int dcl_f (pid_t *pidp, const char *path, \
|
||||
const posix_spawn_file_actions_t *file_actions, \
|
||||
const posix_spawnattr_t *attrp, \
|
||||
char *const argv[], char *const envp[]) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_lineage_intf (); \
|
||||
return gprofng_posix_spawn (real_f, pidp, path, file_actions, attrp, \
|
||||
argv, envp); \
|
||||
}
|
||||
|
||||
|
||||
DCL_FUNC_VER (DCL_POSIX_SPAWN, posix_spawn_2_17, posix_spawn@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_POSIX_SPAWN, posix_spawn_2_15, posix_spawn@GLIBC_2.15)
|
||||
DCL_FUNC_VER (DCL_POSIX_SPAWN, posix_spawn_2_2_5, posix_spawn@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_POSIX_SPAWN, posix_spawn_2_2, posix_spawn@GLIBC_2.2)
|
||||
DCL_POSIX_SPAWN (posix_spawn, CALL_REAL (posix_spawn))
|
||||
|
||||
/*-------------------------------------------------------- posix_spawnp */
|
||||
#if ARCH(Intel)
|
||||
// map interposed symbol versions
|
||||
|
||||
static int
|
||||
__collector_posix_spawnp_symver (int(real_posix_spawnp) (), pid_t *pidp,
|
||||
const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]);
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_posix_spawnp_2_15, posix_spawnp@GLIBC_2.15)
|
||||
int // Common interposition
|
||||
__collector_posix_spawnp_2_15 (pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[])
|
||||
gprofng_posix_spawnp (int (real_posix_spawnp) (),
|
||||
pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[])
|
||||
{
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_posix_spawnp_2_15@%p(path=%s, argv[0]=%s, env[0]=%s)\n",
|
||||
CALL_REAL (posix_spawnp_2_15), path ? path : "NULL", argv ? (argv[0] ? argv[0] : "NULL") : "NULL", envp ? (envp[0] ? envp[0] : "NULL") : "NULL");
|
||||
if (NULL_PTR (posix_spawnp))
|
||||
init_lineage_intf ();
|
||||
return __collector_posix_spawnp_symver (CALL_REAL (posix_spawnp_2_15), pidp,
|
||||
path, file_actions, attrp, argv, envp);
|
||||
}
|
||||
|
||||
#if WSIZE(32)
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_posix_spawnp_2_2, posix_spawnp@GLIBC_2.2)
|
||||
int
|
||||
__collector_posix_spawnp_2_2 (pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[])
|
||||
{
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_posix_spawnp_2_2@%p(path=%s, argv[0]=%s, env[0]=%s)\n",
|
||||
CALL_REAL (posix_spawnp_2_2), path ? path : "NULL", argv ? (argv[0] ? argv[0] : "NULL") : "NULL", envp ? (envp[0] ? envp[0] : "NULL") : "NULL");
|
||||
if (NULL_PTR (posix_spawnp))
|
||||
init_lineage_intf ();
|
||||
return __collector_posix_spawnp_symver (CALL_REAL (posix_spawnp_2_2), pidp,
|
||||
path, file_actions, attrp, argv, envp);
|
||||
}
|
||||
|
||||
#else /* ^WSIZE(32) */
|
||||
SYMVER_ATTRIBUTE (__collector_posix_spawnp_2_2_5, posix_spawnp@GLIBC_2.2.5)
|
||||
int
|
||||
__collector_posix_spawnp_2_2_5 (pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[])
|
||||
{
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_posix_spawnp_2_2_5@%p(path=%s, argv[0]=%s, env[0]=%s)\n",
|
||||
CALL_REAL (posix_spawnp_2_2_5), path ? path : "NULL", argv ? (argv[0] ? argv[0] : "NULL") : "NULL", envp ? (envp[0] ? envp[0] : "NULL") : "NULL");
|
||||
if (NULL_PTR (posix_spawnp))
|
||||
init_lineage_intf ();
|
||||
return __collector_posix_spawnp_symver (CALL_REAL (posix_spawnp_2_2_5), pidp,
|
||||
path, file_actions, attrp, argv, envp);
|
||||
}
|
||||
|
||||
#endif /* ^WSIZE(32) */
|
||||
|
||||
static int
|
||||
__collector_posix_spawnp_symver (int(real_posix_spawnp) (),
|
||||
#else /* ^ARCH(Intel) */
|
||||
int
|
||||
__collector_posix_spawnp (
|
||||
#endif /* ARCH() */
|
||||
pid_t *pidp, const char *path,
|
||||
const posix_spawn_file_actions_t *file_actions,
|
||||
const posix_spawnattr_t *attrp,
|
||||
char *const argv[], char *const envp[]){
|
||||
int ret;
|
||||
static char **coll_env = NULL; /* environment for collection */
|
||||
if (NULL_PTR (posix_spawnp))
|
||||
init_lineage_intf ();
|
||||
if (NULL_PTR (posix_spawnp))
|
||||
|
||||
if (real_posix_spawnp == NULL)
|
||||
{
|
||||
TprintfT (DBG_LT0, "__collector_posix_spawnp(path=%s) interposing: ERROR, posix_spawnp() not found by dlsym\n",
|
||||
TprintfT (DBG_LT0, "gprofng_posix_spawnp (path=%s) interposin ERROR\n",
|
||||
path ? path : "NULL");
|
||||
return -1; /* probably should set errno */
|
||||
}
|
||||
int * guard = NULL;
|
||||
int *guard = NULL;
|
||||
int combo_flag = (line_mode == LM_TRACK_LINEAGE) ? ((CHCK_REENTRANCE (guard)) ? 1 : 0) : 0;
|
||||
TprintfT (DBG_LT0, "__collector_posix_spawnp(path=%s, argv[0]=%s, env[0]=%s) interposing: line_mode=%d combo=%d\n",
|
||||
path ? path : "NULL", argv ? (argv[0] ? argv[0] : "NULL") : "NULL",
|
||||
envp ? (envp[0] ? envp[0] : "NULL") : "NULL", line_mode, combo_flag);
|
||||
TprintfT (DBG_LT0, "gprofng_posix_spawnp @%p (path=%s, argv[0]=%s, env[0]=%s) line_mode=%d combo=%d\n",
|
||||
real_posix_spawnp, path ? path : "NULL",
|
||||
argv && argv[0] ? argv[0] : "NULL",
|
||||
envp && envp[0] ? envp[0] : "NULL", line_mode, combo_flag);
|
||||
|
||||
if (line_mode == LM_CLOSED) /* ensure collection environment is sanitised */
|
||||
if (line_mode == LM_CLOSED) /* ensure collection environment is sanitized */
|
||||
__collector_env_unset ((char**) envp);
|
||||
if (line_mode != LM_TRACK_LINEAGE || combo_flag)
|
||||
{
|
||||
#if ARCH(Intel)
|
||||
return (real_posix_spawnp) (pidp, path, file_actions, attrp, argv, envp);
|
||||
#else
|
||||
return CALL_REAL (posix_spawnp)(pidp, path, file_actions, attrp, argv, envp);
|
||||
#endif
|
||||
}
|
||||
return (real_posix_spawnp) (pidp, path, file_actions, attrp, argv, envp);
|
||||
int following_exec = 0;
|
||||
coll_env = linetrace_ext_exec_prologue ("posix_spawnp", path, argv, envp, &following_exec);
|
||||
TprintfT (DBG_LT0, "__collector_posix_spawnp(): coll_env=0x%p\n", coll_env);
|
||||
__collector_env_printall ("__collector_posix_spawnp", coll_env);
|
||||
PUSH_REENTRANCE (guard);
|
||||
#if ARCH(Intel)
|
||||
ret = (real_posix_spawnp) (pidp, path, file_actions, attrp, argv, coll_env);
|
||||
#else
|
||||
ret = CALL_REAL (posix_spawnp)(pidp, path, file_actions, attrp, argv, coll_env);
|
||||
#endif
|
||||
int ret = real_posix_spawnp (pidp, path, file_actions, attrp, argv, coll_env);
|
||||
POP_REENTRANCE (guard);
|
||||
linetrace_ext_exec_epilogue ("posix_spawnp", envp, ret, &following_exec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DCL_POSIX_SPAWNP(dcl_f, real_f) \
|
||||
int dcl_f (pid_t *pidp, const char *path, \
|
||||
const posix_spawn_file_actions_t *file_actions, \
|
||||
const posix_spawnattr_t *attrp, \
|
||||
char *const argv[], char *const envp[]) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_lineage_intf (); \
|
||||
return gprofng_posix_spawnp (real_f, pidp, path, \
|
||||
file_actions, attrp, argv, envp); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_POSIX_SPAWNP, posix_spawnp_2_17, posix_spawnp@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_POSIX_SPAWNP, posix_spawnp_2_15, posix_spawnp@GLIBC_2.15)
|
||||
DCL_FUNC_VER (DCL_POSIX_SPAWNP, posix_spawnp_2_2_5, posix_spawnp@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_POSIX_SPAWNP, posix_spawnp_2_2, posix_spawnp@GLIBC_2.2)
|
||||
DCL_POSIX_SPAWNP (posix_spawnp, CALL_REAL (posix_spawnp))
|
||||
|
||||
/*------------------------------------------------------------- system */
|
||||
int system () __attribute__ ((weak, alias ("__collector_system")));
|
||||
|
||||
@ -1612,90 +1529,33 @@ __collector_system (const char *cmd)
|
||||
|
||||
/*------------------------------------------------------------- popen */
|
||||
// map interposed symbol versions
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
static FILE *
|
||||
__collector_popen_symver (FILE*(real_popen) (), const char *cmd, const char *mode);
|
||||
#define DCL_POPEN(dcl_f, real_f) \
|
||||
FILE *dcl_f (const char *cmd, const char *mode) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_lineage_intf (); \
|
||||
TprintfT (DBG_LT0, #dcl_f " (%s) interposing: line_mode=%d combo=%d\n", \
|
||||
cmd ? cmd : "NULL", line_mode, get_combo_flag ()); \
|
||||
int *guard = NULL; \
|
||||
if (line_mode == LM_TRACK_LINEAGE) \
|
||||
INIT_REENTRANCE (guard); \
|
||||
if (guard == NULL) \
|
||||
return (real_f) (cmd, mode); \
|
||||
int following_combo = 0; \
|
||||
linetrace_ext_combo_prologue ("popen", cmd, &following_combo); \
|
||||
PUSH_REENTRANCE (guard); \
|
||||
FILE *ret = (real_f) (cmd, mode); \
|
||||
POP_REENTRANCE (guard); \
|
||||
linetrace_ext_combo_epilogue ("popen", ret == NULL ? -1 : 0, \
|
||||
&following_combo); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_popen_2_1, popen@GLIBC_2.1)
|
||||
FILE *
|
||||
__collector_popen_2_1 (const char *cmd, const char *mode)
|
||||
{
|
||||
if (NULL_PTR (popen))
|
||||
init_lineage_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_popen_2_1@%p\n", CALL_REAL (popen_2_1));
|
||||
return __collector_popen_symver (CALL_REAL (popen_2_1), cmd, mode);
|
||||
}
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_popen_2_0, popen@GLIBC_2.0)
|
||||
FILE *
|
||||
__collector_popen_2_0 (const char *cmd, const char *mode)
|
||||
{
|
||||
if (NULL_PTR (popen))
|
||||
init_lineage_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_popen_2_0@%p\n", CALL_REAL (popen_2_0));
|
||||
return __collector_popen_symver (CALL_REAL (popen_2_0), cmd, mode);
|
||||
}
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector__popen_2_1, _popen@GLIBC_2.1)
|
||||
FILE *
|
||||
__collector__popen_2_1 (const char *cmd, const char *mode)
|
||||
{
|
||||
if (NULL_PTR (popen))
|
||||
init_lineage_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector__popen_2_1@%p\n", CALL_REAL (popen_2_1));
|
||||
return __collector_popen_symver (CALL_REAL (popen_2_1), cmd, mode);
|
||||
}
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector__popen_2_0, _popen@GLIBC_2.0)
|
||||
FILE *
|
||||
__collector__popen_2_0 (const char *cmd, const char *mode)
|
||||
{
|
||||
if (NULL_PTR (popen))
|
||||
init_lineage_intf ();
|
||||
return __collector_popen_symver (CALL_REAL (popen_2_0), cmd, mode);
|
||||
}
|
||||
#else // WSIZE(64)
|
||||
FILE * popen () __attribute__ ((weak, alias ("__collector_popen")));
|
||||
#endif
|
||||
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
static FILE *
|
||||
__collector_popen_symver (FILE*(real_popen) (), const char *cmd, const char *mode)
|
||||
#else
|
||||
|
||||
FILE *
|
||||
__collector_popen (const char *cmd, const char *mode)
|
||||
#endif
|
||||
{
|
||||
FILE *ret;
|
||||
if (NULL_PTR (popen))
|
||||
init_lineage_intf ();
|
||||
TprintfT (DBG_LT0,
|
||||
"__collector_popen(cmd=%s) interposing: line_mode=%d combo=%d\n",
|
||||
cmd ? cmd : "NULL", line_mode, get_combo_flag ());
|
||||
int *guard = NULL;
|
||||
if (line_mode == LM_TRACK_LINEAGE)
|
||||
INIT_REENTRANCE (guard);
|
||||
if (guard == NULL)
|
||||
{
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
return (real_popen) (cmd, mode);
|
||||
#else
|
||||
return CALL_REAL (popen)(cmd, mode);
|
||||
#endif
|
||||
}
|
||||
int following_combo = 0;
|
||||
linetrace_ext_combo_prologue ("popen", cmd, &following_combo);
|
||||
PUSH_REENTRANCE (guard);
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
ret = (real_popen) (cmd, mode);
|
||||
#else
|
||||
ret = CALL_REAL (popen)(cmd, mode);
|
||||
#endif
|
||||
POP_REENTRANCE (guard);
|
||||
linetrace_ext_combo_epilogue ("popen", (ret == NULL) ? (-1) : 0, &following_combo);
|
||||
return ret;
|
||||
}
|
||||
DCL_FUNC_VER (DCL_POPEN, popen_2_17, popen@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_POPEN, popen_2_2_5, popen@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_POPEN, popen_2_1, popen@GLIBC_2.1)
|
||||
DCL_FUNC_VER (DCL_POPEN, popen_2_0, popen@GLIBC_2.0)
|
||||
DCL_POPEN (popen, CALL_REAL (popen))
|
||||
|
||||
/*------------------------------------------------------------- grantpt */
|
||||
int grantpt () __attribute__ ((weak, alias ("__collector_grantpt")));
|
||||
|
@ -1,40 +0,0 @@
|
||||
/* Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
Contributed by Oracle.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
GLIBC_2.17 {
|
||||
global:
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_join;
|
||||
sem_wait;
|
||||
pthread_create;
|
||||
dlopen;
|
||||
popen;
|
||||
timer_create;
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
fopen;
|
||||
fclose;
|
||||
fdopen;
|
||||
fgetpos;
|
||||
fsetpos;
|
||||
};
|
@ -1,79 +0,0 @@
|
||||
/* Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
Contributed by Oracle.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
GLIBC_2.2.5 {
|
||||
global:
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_join;
|
||||
sem_wait;
|
||||
pthread_create;
|
||||
dlopen;
|
||||
popen;
|
||||
timer_create;
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
fopen;
|
||||
fclose;
|
||||
fdopen;
|
||||
fgetpos;
|
||||
fsetpos;
|
||||
};
|
||||
|
||||
GLIBC_2.3.2 {
|
||||
global:
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
};
|
||||
|
||||
GLIBC_2.3.3 {
|
||||
global:
|
||||
timer_create;
|
||||
};
|
||||
|
||||
GLIBC_2.15 {
|
||||
global:
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
};
|
||||
|
||||
GLIBC_2.17 {
|
||||
global:
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_join;
|
||||
sem_wait;
|
||||
pthread_create;
|
||||
dlopen;
|
||||
popen;
|
||||
timer_create;
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
fopen;
|
||||
fclose;
|
||||
fdopen;
|
||||
fgetpos;
|
||||
fsetpos;
|
||||
};
|
||||
|
@ -1,81 +0,0 @@
|
||||
/* Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
Contributed by Oracle.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
GLIBC_2.0 {
|
||||
global:
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_join;
|
||||
pthread_create;
|
||||
dlopen;
|
||||
popen;
|
||||
sem_wait;
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
fopen;
|
||||
fclose;
|
||||
fdopen;
|
||||
fgetpos;
|
||||
fsetpos;
|
||||
};
|
||||
|
||||
GLIBC_2.1 {
|
||||
global:
|
||||
sem_wait;
|
||||
pthread_create;
|
||||
dlopen;
|
||||
open64;
|
||||
pread;
|
||||
pwrite;
|
||||
pwrite64;
|
||||
popen;
|
||||
fopen;
|
||||
fclose;
|
||||
fdopen;
|
||||
fgetpos64;
|
||||
fsetpos64;
|
||||
};
|
||||
|
||||
GLIBC_2.2 {
|
||||
global:
|
||||
open64;
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
pread;
|
||||
pwrite;
|
||||
pwrite64;
|
||||
timer_create;
|
||||
fgetpos;
|
||||
fsetpos;
|
||||
fgetpos64;
|
||||
fsetpos64;
|
||||
};
|
||||
|
||||
GLIBC_2.3.2 {
|
||||
global:
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
};
|
||||
|
||||
GLIBC_2.15 {
|
||||
global:
|
||||
posix_spawn;
|
||||
posix_spawnp;
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
/* Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
Contributed by Oracle.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
GLIBC_2.0 {
|
||||
global:
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_join;
|
||||
};
|
||||
|
||||
GLIBC_2.1 {
|
||||
global:
|
||||
sem_wait;
|
||||
pthread_create;
|
||||
dlopen;
|
||||
popen;
|
||||
};
|
||||
|
||||
GLIBC_2.3.2 {
|
||||
global:
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
};
|
@ -1,58 +0,0 @@
|
||||
/* Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
Contributed by Oracle.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
GLIBC_2.0 {
|
||||
global:
|
||||
dlopen;
|
||||
};
|
||||
|
||||
GLIBC_2.1 {
|
||||
global:
|
||||
dlopen;
|
||||
};
|
||||
|
||||
GLIBC_2.2 {
|
||||
global:
|
||||
pthread_create;
|
||||
popen;
|
||||
pthread_mutex_lock;
|
||||
pthread_mutex_unlock;
|
||||
pthread_join;
|
||||
sem_wait;
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
timer_create;
|
||||
fopen;
|
||||
fclose;
|
||||
fdopen;
|
||||
fgetpos;
|
||||
fsetpos;
|
||||
};
|
||||
|
||||
GLIBC_2.3.2 {
|
||||
global:
|
||||
pthread_cond_wait;
|
||||
pthread_cond_timedwait;
|
||||
};
|
||||
|
||||
GLIBC_2.3.3 {
|
||||
global:
|
||||
timer_create;
|
||||
};
|
@ -61,12 +61,6 @@ typedef struct prmap_t
|
||||
int pr_pagesize; /* pagesize (bytes) for this mapping */
|
||||
} prmap_t;
|
||||
|
||||
#define SYS_MMAP_NAME "mmap"
|
||||
#define SYS_MMAP64_NAME "mmap64"
|
||||
#define SYS_MUNMAP_NAME "munmap"
|
||||
#define SYS_DLOPEN_NAME "dlopen"
|
||||
#define SYS_DLCLOSE_NAME "dlclose"
|
||||
|
||||
typedef struct MapInfo
|
||||
{
|
||||
struct MapInfo *next;
|
||||
@ -113,11 +107,17 @@ static void *(*__real_mmap64)(void* start, size_t length, int prot, int flags,
|
||||
int fd, off64_t offset) = NULL;
|
||||
static int (*__real_munmap)(void* start, size_t length) = NULL;
|
||||
static void *(*__real_dlopen)(const char* pathname, int mode) = NULL;
|
||||
#if (ARCH(Intel) && WSIZE(32)) || ARCH(SPARC)
|
||||
static void *(*__real_dlopen_2_34)(const char* pathname, int mode) = NULL;
|
||||
static void *(*__real_dlopen_2_17)(const char* pathname, int mode) = NULL;
|
||||
static void *(*__real_dlopen_2_2_5)(const char* pathname, int mode) = NULL;
|
||||
static void *(*__real_dlopen_2_1)(const char* pathname, int mode) = NULL;
|
||||
static void *(*__real_dlopen_2_0)(const char* pathname, int mode) = NULL;
|
||||
#endif
|
||||
|
||||
static int (*__real_dlclose)(void* handle) = NULL;
|
||||
static int (*__real_dlclose_2_34)(void* handle) = NULL;
|
||||
static int (*__real_dlclose_2_17)(void* handle) = NULL;
|
||||
static int (*__real_dlclose_2_2_5)(void* handle) = NULL;
|
||||
static int (*__real_dlclose_2_0)(void* handle) = NULL;
|
||||
static void (*collector_heap_record)(int, size_t, void*) = NULL;
|
||||
|
||||
/* internal function prototypes */
|
||||
@ -1408,17 +1408,15 @@ init_mmap_intf ()
|
||||
{
|
||||
if (__collector_dlsym_guard)
|
||||
return 1;
|
||||
void *dlflag;
|
||||
__real_mmap = (void*(*)(void* addr, size_t len, int prot, int flags,
|
||||
int fildes, off_t off))dlsym (RTLD_NEXT, SYS_MMAP_NAME);
|
||||
void *dlflag = RTLD_NEXT;
|
||||
__real_mmap = dlsym (dlflag, "mmap");
|
||||
if (__real_mmap == NULL)
|
||||
{
|
||||
|
||||
/* We are probably dlopened after libthread/libc,
|
||||
* try to search in the previously loaded objects
|
||||
*/
|
||||
__real_mmap = (void*(*)(void* addr, size_t len, int prot, int flags,
|
||||
int fildes, off_t off))dlsym (RTLD_DEFAULT, SYS_MMAP_NAME);
|
||||
__real_mmap = dlsym (RTLD_DEFAULT, "mmap");
|
||||
if (__real_mmap == NULL)
|
||||
{
|
||||
TprintfT (0, "ERROR: collector real mmap not found\n");
|
||||
@ -1427,33 +1425,59 @@ init_mmap_intf ()
|
||||
TprintfT (DBG_LT2, "collector real mmap found with RTLD_DEFAULT\n");
|
||||
dlflag = RTLD_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
TprintfT (DBG_LT2, "collector real mmap found with RTLD_NEXT\n");
|
||||
dlflag = RTLD_NEXT;
|
||||
}
|
||||
|
||||
TprintfT (DBG_LT2, "init_mmap_intf() @%p __real_mmap\n", __real_mmap);
|
||||
__real_mmap64 = (void*(*)(void *, size_t, int, int, int, off64_t))
|
||||
dlsym (dlflag, SYS_MMAP64_NAME);
|
||||
TprintfT (DBG_LT2, "init_mmap_intf() @%p __real_mmap64\n", __real_mmap64);
|
||||
__real_munmap = (int(*)(void *, size_t)) dlsym (dlflag, SYS_MUNMAP_NAME);
|
||||
TprintfT (DBG_LT2, "init_mmap_intf() @%p __real_munmap\n", __real_munmap);
|
||||
__real_mmap64 = dlsym (dlflag, "mmap64");
|
||||
__real_munmap = dlsym (dlflag, "munmap");
|
||||
|
||||
// dlopen/dlmopen/dlclose are in libdl.so
|
||||
__real_dlopen = (void*(*)(const char *, int))
|
||||
dlvsym (dlflag, SYS_DLOPEN_NAME, SYS_DLOPEN_VERSION);
|
||||
TprintfT (DBG_LT2, "init_mmap_intf() [%s] @%p __real_dlopen\n",
|
||||
SYS_DLOPEN_VERSION, __real_dlopen);
|
||||
#if (ARCH(Intel) && WSIZE(32)) || ARCH(SPARC)
|
||||
__real_dlopen_2_1 = __real_dlopen;
|
||||
__real_dlopen_2_0 = (void*(*)(const char *, int))
|
||||
dlvsym (dlflag, SYS_DLOPEN_NAME, "GLIBC_2.0");
|
||||
#endif
|
||||
__real_dlopen_2_34 = dlvsym (dlflag, "dlopen", "GLIBC_2.34");
|
||||
__real_dlopen_2_17 = dlvsym (dlflag, "dlopen", "GLIBC_2.17");
|
||||
__real_dlopen_2_2_5 = dlvsym (dlflag, "dlopen", "GLIBC_2.2.5");
|
||||
__real_dlopen_2_1 = dlvsym (dlflag, "dlopen", "GLIBC_2.1");
|
||||
__real_dlopen_2_0 = dlvsym (dlflag, "dlopen", "GLIBC_2.0");
|
||||
if (__real_dlopen_2_34)
|
||||
__real_dlopen = __real_dlopen_2_34;
|
||||
else if (__real_dlopen_2_17)
|
||||
__real_dlopen = __real_dlopen_2_17;
|
||||
else if (__real_dlopen_2_2_5)
|
||||
__real_dlopen = __real_dlopen_2_2_5;
|
||||
else if (__real_dlopen_2_1)
|
||||
__real_dlopen = __real_dlopen_2_1;
|
||||
else if (__real_dlopen_2_0)
|
||||
__real_dlopen = __real_dlopen_2_0;
|
||||
else
|
||||
__real_dlopen = dlsym (dlflag, "dlopen");
|
||||
|
||||
__real_dlclose_2_34 = dlvsym (dlflag, "dlclose", "GLIBC_2.34");
|
||||
__real_dlclose_2_17 = dlvsym (dlflag, "dlclose", "GLIBC_2.17");
|
||||
__real_dlclose_2_2_5 = dlvsym (dlflag, "dlclose", "GLIBC_2.2.5");
|
||||
__real_dlclose_2_0 = dlvsym (dlflag, "dlclose", "GLIBC_2.0");
|
||||
if (__real_dlclose_2_34)
|
||||
__real_dlclose = __real_dlclose_2_34;
|
||||
else if (__real_dlclose_2_17)
|
||||
__real_dlclose = __real_dlclose_2_17;
|
||||
else if (__real_dlclose_2_2_5)
|
||||
__real_dlclose = __real_dlclose_2_2_5;
|
||||
else if (__real_dlclose_2_0)
|
||||
__real_dlclose = __real_dlclose_2_0;
|
||||
else
|
||||
__real_dlclose = dlsym (dlflag, "dlclose");
|
||||
|
||||
__real_dlclose = (int(*)(void* handle))dlsym (dlflag, SYS_DLCLOSE_NAME);
|
||||
TprintfT (DBG_LT2, "init_mmap_intf() @%p __real_dlclose\n", __real_dlclose);
|
||||
TprintfT (DBG_LT2, "init_mmap_intf() done\n");
|
||||
#define PR_FUNC(f) TprintfT (DBG_LT2, " mmaptrace.c: " #f ": @%p\n", f)
|
||||
PR_FUNC (__real_dlclose);
|
||||
PR_FUNC (__real_dlclose_2_0);
|
||||
PR_FUNC (__real_dlclose_2_17);
|
||||
PR_FUNC (__real_dlclose_2_2_5);
|
||||
PR_FUNC (__real_dlclose_2_34);
|
||||
PR_FUNC (__real_dlopen);
|
||||
PR_FUNC (__real_dlopen_2_0);
|
||||
PR_FUNC (__real_dlopen_2_1);
|
||||
PR_FUNC (__real_dlopen_2_17);
|
||||
PR_FUNC (__real_dlopen_2_2_5);
|
||||
PR_FUNC (__real_dlopen_2_34);
|
||||
PR_FUNC (__real_mmap);
|
||||
PR_FUNC (__real_mmap64);
|
||||
PR_FUNC (__real_munmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1530,8 +1554,8 @@ munmap (void *start, size_t length)
|
||||
|
||||
/*------------------------------------------------------------- dlopen */
|
||||
static void *
|
||||
__collector_dlopen_symver (void*(real_dlopen) (const char *, int),
|
||||
void *caller, const char *pathname, int mode)
|
||||
gprofng_dlopen (void*(real_dlopen) (const char *, int),
|
||||
void *caller, const char *pathname, int mode)
|
||||
{
|
||||
const char * real_pathname = pathname;
|
||||
char new_pathname[MAXPATHLEN];
|
||||
@ -1552,15 +1576,15 @@ __collector_dlopen_symver (void*(real_dlopen) (const char *, int),
|
||||
const char *p = __collector_strrchr (dl_info.dli_fname, '/');
|
||||
if (p)
|
||||
__collector_strlcpy (new_pathname, dl_info.dli_fname,
|
||||
(p - dl_info.dli_fname + 2) < MAXPATHLEN ? (p - dl_info.dli_fname + 2) : MAXPATHLEN);
|
||||
__collector_strlcat (new_pathname, pathname + origin_offset, MAXPATHLEN - CALL_UTIL (strlen)(new_pathname));
|
||||
(p - dl_info.dli_fname + 2) < MAXPATHLEN ?
|
||||
(p - dl_info.dli_fname + 2) : MAXPATHLEN);
|
||||
__collector_strlcat (new_pathname, pathname + origin_offset,
|
||||
MAXPATHLEN - CALL_UTIL (strlen)(new_pathname));
|
||||
real_pathname = new_pathname;
|
||||
}
|
||||
else
|
||||
TprintfT (0, "ERROR: dladdr(%p): %s\n", caller, dlerror ());
|
||||
}
|
||||
if (NULL_PTR (dlopen))
|
||||
init_mmap_intf ();
|
||||
TprintfT (DBG_LT2, "libcollector.dlopen(%s,%d) interposing\n",
|
||||
pathname ? pathname : "", mode);
|
||||
void *ret = NULL;
|
||||
@ -1585,46 +1609,26 @@ __collector_dlopen_symver (void*(real_dlopen) (const char *, int),
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
dlopen (const char *pathname, int mode)
|
||||
{
|
||||
if (NULL_PTR (dlopen))
|
||||
init_mmap_intf ();
|
||||
void* caller = __builtin_return_address (0); // must be called inside dlopen first layer interposition
|
||||
return __collector_dlopen_symver (CALL_REAL (dlopen), caller, pathname, mode);
|
||||
}
|
||||
#define DCL_DLOPEN(dcl_f, real_f) \
|
||||
void *dcl_f (const char *pathname, int mode) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_mmap_intf (); \
|
||||
void *caller = __builtin_return_address (0); \
|
||||
return gprofng_dlopen (real_f, caller, pathname, mode); \
|
||||
}
|
||||
|
||||
#if !defined(__MUSL_LIBC) && ((ARCH(Intel) && WSIZE(32)) || ARCH(SPARC))
|
||||
// map interposed symbol versions
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_dlopen_2_1, dlopen@GLIBC_2.1)
|
||||
void *
|
||||
__collector_dlopen_2_1 (const char *pathname, int mode)
|
||||
{
|
||||
if (NULL_PTR (dlopen_2_1))
|
||||
init_mmap_intf ();
|
||||
void *caller = __builtin_return_address (0); // must be called inside dlopen first layer interposition
|
||||
return __collector_dlopen_symver (CALL_REAL (dlopen_2_1), caller, pathname, mode);
|
||||
}
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_dlopen_2_0, dlopen@GLIBC_2.0)
|
||||
void *
|
||||
__collector_dlopen_2_0 (const char *pathname, int mode)
|
||||
{
|
||||
if (NULL_PTR (dlopen_2_0))
|
||||
init_mmap_intf ();
|
||||
void* caller = __builtin_return_address (0); // must be called inside dlopen first layer interposition
|
||||
return __collector_dlopen_symver (CALL_REAL (dlopen_2_0), caller, pathname, mode);
|
||||
}
|
||||
#endif
|
||||
DCL_FUNC_VER (DCL_DLOPEN, dlopen_2_34, dlopen@GLIBC_2.34)
|
||||
DCL_FUNC_VER (DCL_DLOPEN, dlopen_2_17, dlopen@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_DLOPEN, dlopen_2_2_5, dlopen@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_DLOPEN, dlopen_2_1, dlopen@GLIBC_2.1)
|
||||
DCL_FUNC_VER (DCL_DLOPEN, dlopen_2_0, dlopen@GLIBC_2.0)
|
||||
DCL_DLOPEN (dlopen, CALL_REAL (dlopen))
|
||||
|
||||
/*------------------------------------------------------------- dlclose */
|
||||
int
|
||||
dlclose (void *handle)
|
||||
static int
|
||||
gprofng_dlclose (int (real_dlclose) (void *), void *handle)
|
||||
{
|
||||
if (NULL_PTR (dlclose))
|
||||
init_mmap_intf ();
|
||||
TprintfT (DBG_LT2, "__collector_dlclose(%p) entered\n", handle);
|
||||
hrtime_t hrt = GETRELTIME ();
|
||||
if (!CHCK_REENTRANCE)
|
||||
{
|
||||
@ -1633,7 +1637,7 @@ dlclose (void *handle)
|
||||
POP_REENTRANCE;
|
||||
hrt = GETRELTIME ();
|
||||
}
|
||||
int ret = CALL_REAL (dlclose)(handle);
|
||||
int ret = real_dlclose (handle);
|
||||
|
||||
/* Don't call update if dlclose failed: preserve dlerror() */
|
||||
if (!ret && !CHCK_REENTRANCE)
|
||||
@ -1642,6 +1646,21 @@ dlclose (void *handle)
|
||||
update_map_segments (hrt, 1);
|
||||
POP_REENTRANCE;
|
||||
}
|
||||
TprintfT (DBG_LT2, "__collector_dlclose(%p) returning %d\n", handle, ret);
|
||||
TprintfT (DBG_LT2, "gprofng_dlclose @%p (%p) returning %d\n", real_dlclose,
|
||||
handle, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DCL_DLCLOSE(dcl_f, real_f) \
|
||||
int dcl_f (void *handle) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_mmap_intf (); \
|
||||
return gprofng_dlclose (real_f, handle); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_DLCLOSE, dlclose_2_34, dlclose@GLIBC_2.34)
|
||||
DCL_FUNC_VER (DCL_DLCLOSE, dlclose_2_17, dlclose@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_DLCLOSE, dlclose_2_2_5, dlclose@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_DLCLOSE, dlclose_2_0, dlclose@GLIBC_2.0)
|
||||
DCL_DLCLOSE (dlclose, CALL_REAL (dlclose))
|
||||
|
@ -95,6 +95,9 @@ static long int (*__real_strtol)(const char *nptr, char **endptr, int base) = NU
|
||||
static int (*__real_fprintf) (FILE *stream, const char *format, ...) = NULL;
|
||||
static void (*__real___collector_jprofile_enable_synctrace) (void) = NULL;
|
||||
static int (*__real_pthread_mutex_lock) (pthread_mutex_t *mutex) = NULL;
|
||||
static int (*__real_pthread_mutex_lock_2_17) (pthread_mutex_t *mutex) = NULL;
|
||||
static int (*__real_pthread_mutex_lock_2_2_5) (pthread_mutex_t *mutex) = NULL;
|
||||
static int (*__real_pthread_mutex_lock_2_0) (pthread_mutex_t *mutex) = NULL;
|
||||
static int (*__real_pthread_mutex_unlock) (pthread_mutex_t *mutex) = NULL;
|
||||
static int (*__real_pthread_cond_wait) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex) = NULL;
|
||||
@ -102,31 +105,37 @@ static int (*__real_pthread_cond_timedwait) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex,
|
||||
const struct timespec *restrict abstime) = NULL;
|
||||
static int (*__real_pthread_join) (pthread_t thread, void **retval) = NULL;
|
||||
static int (*__real_pthread_join_2_34) (pthread_t thread, void **retval) = NULL;
|
||||
static int (*__real_pthread_join_2_17) (pthread_t thread, void **retval) = NULL;
|
||||
static int (*__real_pthread_join_2_2_5) (pthread_t thread, void **retval) = NULL;
|
||||
static int (*__real_pthread_join_2_0) (pthread_t thread, void **retval) = NULL;
|
||||
static int (*__real_sem_wait) (sem_t *sem) = NULL;
|
||||
static int (*__real_sem_wait_2_34) (sem_t *sem) = NULL;
|
||||
static int (*__real_sem_wait_2_17) (sem_t *sem) = NULL;
|
||||
static int (*__real_sem_wait_2_2_5) (sem_t *sem) = NULL;
|
||||
static int (*__real_sem_wait_2_1) (sem_t *sem) = NULL;
|
||||
static int (*__real_sem_wait_2_0) (sem_t *sem) = NULL;
|
||||
static int (*__real_pthread_cond_wait_2_17) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex) = NULL;
|
||||
static int (*__real_pthread_cond_wait_2_3_2) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex) = NULL;
|
||||
static int (*__real_pthread_cond_wait_2_2_5) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex) = NULL;
|
||||
static int (*__real_pthread_cond_wait_2_0) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex) = NULL;
|
||||
static int (*__real_pthread_cond_timedwait_2_17) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex,
|
||||
const struct timespec *restrict abstime) = NULL;
|
||||
static int (*__real_pthread_cond_timedwait_2_3_2) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex,
|
||||
const struct timespec *restrict abstime) = NULL;
|
||||
|
||||
#if WSIZE(32)
|
||||
static int (*__real_sem_wait_2_1) (sem_t *sem) = NULL;
|
||||
static int (*__real_sem_wait_2_0) (sem_t *sem) = NULL;
|
||||
static int (*__real_pthread_cond_wait_2_0) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex) = NULL;
|
||||
static int (*__real_pthread_cond_timedwait_2_2_5) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex,
|
||||
const struct timespec *restrict abstime) = NULL;
|
||||
static int (*__real_pthread_cond_timedwait_2_0) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex,
|
||||
const struct timespec *restrict abstime) = NULL;
|
||||
#elif WSIZE(64)
|
||||
#if ARCH(Intel)
|
||||
static int (*__real_pthread_cond_wait_2_2_5) (pthread_cond_t *restrict cond,
|
||||
pthread_mutex_t *restrict mutex) = NULL;
|
||||
static void *__real_pthread_cond_timedwait_2_2_5 = NULL;
|
||||
#elif ARCH(SPARC)
|
||||
static void *__real_pthread_cond_wait_2_2 = NULL;
|
||||
static void *__real_pthread_cond_timedwait_2_2 = NULL;
|
||||
#endif /* ARCH() */
|
||||
#endif /* WSIZE() */
|
||||
|
||||
|
||||
static void
|
||||
collector_memset (void *s, int c, size_t n)
|
||||
@ -348,6 +357,23 @@ sync_calibrate ()
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
init_pthread_mutex_lock (void *dlflag)
|
||||
{
|
||||
__real_pthread_mutex_lock_2_17 = dlvsym (dlflag, "pthread_mutex_lock", "GLIBC_2.17");
|
||||
__real_pthread_mutex_lock_2_2_5 = dlvsym (dlflag, "pthread_mutex_lock", "GLIBC_2.2.5");
|
||||
__real_pthread_mutex_lock_2_0 = dlvsym (dlflag, "pthread_mutex_lock", "GLIBC_2.0");
|
||||
if (__real_pthread_mutex_lock_2_17)
|
||||
__real_pthread_mutex_lock = __real_pthread_mutex_lock_2_17;
|
||||
else if (__real_pthread_mutex_lock_2_2_5)
|
||||
__real_pthread_mutex_lock = __real_pthread_mutex_lock_2_2_5;
|
||||
else if (__real_pthread_mutex_lock_2_0)
|
||||
__real_pthread_mutex_lock = __real_pthread_mutex_lock_2_0;
|
||||
else
|
||||
__real_pthread_mutex_lock = dlsym (dlflag, "pthread_mutex_lock");
|
||||
return __real_pthread_mutex_lock ? 1 : 0;
|
||||
}
|
||||
|
||||
static int
|
||||
init_thread_intf ()
|
||||
{
|
||||
@ -384,280 +410,118 @@ init_thread_intf ()
|
||||
sync_java = 0;
|
||||
}
|
||||
|
||||
#if WSIZE(32)
|
||||
/* ########################################## begin WSIZE(32) */
|
||||
/* IMPORTANT!! The GLIBC_* versions below must match those in the er_sync.*.mapfile ! */
|
||||
dlflag = RTLD_NEXT;
|
||||
ptr = dlvsym (dlflag, "pthread_mutex_lock", "GLIBC_2.0");
|
||||
if (ptr == NULL)
|
||||
if (init_pthread_mutex_lock (dlflag) == 0)
|
||||
{
|
||||
/* We are probably dlopened after libthread/libc,
|
||||
* try to search in the previously loaded objects
|
||||
*/
|
||||
dlflag = RTLD_DEFAULT;
|
||||
ptr = dlvsym (dlflag, "pthread_mutex_lock", "GLIBC_2.0");
|
||||
if (ptr != NULL)
|
||||
{
|
||||
__real_pthread_mutex_lock = ptr;
|
||||
Tprintf (0, "synctrace: WARNING: init_thread_intf() using RTLD_DEFAULT for OS sync routines\n");
|
||||
}
|
||||
else
|
||||
if (init_pthread_mutex_lock (dlflag) == 0)
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_mutex_lock\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
__real_pthread_mutex_lock = ptr;
|
||||
|
||||
ptr = dlvsym (dlflag, "pthread_mutex_unlock", "GLIBC_2.0");
|
||||
if (ptr)
|
||||
__real_pthread_mutex_unlock = (void *) ptr;
|
||||
if ((ptr = dlvsym (dlflag, "pthread_mutex_unlock", "GLIBC_2.17")) != NULL)
|
||||
__real_pthread_mutex_unlock = ptr;
|
||||
else if ((ptr = dlvsym (dlflag, "pthread_mutex_unlock", "GLIBC_2.2.5")) != NULL)
|
||||
__real_pthread_mutex_unlock = ptr;
|
||||
else if ((ptr = dlvsym (dlflag, "pthread_mutex_unlock", "GLIBC_2.0")) != NULL)
|
||||
__real_pthread_mutex_unlock = ptr;
|
||||
else
|
||||
__real_pthread_mutex_unlock = dlsym (dlflag, "pthread_mutex_unlock");
|
||||
if (__real_pthread_mutex_unlock == NULL)
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_mutex_unlock\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.3.2");
|
||||
if (ptr)
|
||||
__real_pthread_cond_wait = (void *) ptr;
|
||||
|
||||
__real_pthread_cond_wait_2_17 = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.17");
|
||||
__real_pthread_cond_wait_2_3_2 = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.3.2");
|
||||
__real_pthread_cond_wait_2_2_5 = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.2.5");
|
||||
__real_pthread_cond_wait_2_0 = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.0");
|
||||
if (__real_pthread_cond_wait_2_17)
|
||||
__real_pthread_cond_wait = __real_pthread_cond_wait_2_17;
|
||||
else if (__real_pthread_cond_wait_2_3_2)
|
||||
__real_pthread_cond_wait = __real_pthread_cond_wait_2_3_2;
|
||||
else if (__real_pthread_cond_wait_2_2_5)
|
||||
__real_pthread_cond_wait = __real_pthread_cond_wait_2_2_5;
|
||||
else if (__real_pthread_cond_wait_2_0)
|
||||
__real_pthread_cond_wait = __real_pthread_cond_wait_2_0;
|
||||
else
|
||||
__real_pthread_cond_wait = dlsym (dlflag, "pthread_cond_wait");
|
||||
if (__real_pthread_cond_wait == NULL)
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_wait\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.3.2");
|
||||
if (ptr)
|
||||
__real_pthread_cond_timedwait = (void *) ptr;
|
||||
|
||||
__real_pthread_cond_timedwait_2_17 = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.17");
|
||||
__real_pthread_cond_timedwait_2_3_2 = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.3.2");
|
||||
__real_pthread_cond_timedwait_2_2_5 = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.2.5");
|
||||
__real_pthread_cond_timedwait_2_0 = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.0");
|
||||
if (__real_pthread_cond_timedwait_2_17)
|
||||
__real_pthread_cond_timedwait = __real_pthread_cond_timedwait_2_17;
|
||||
else if (__real_pthread_cond_timedwait_2_3_2)
|
||||
__real_pthread_cond_timedwait = __real_pthread_cond_timedwait_2_3_2;
|
||||
else if (__real_pthread_cond_timedwait_2_2_5)
|
||||
__real_pthread_cond_timedwait = __real_pthread_cond_timedwait_2_2_5;
|
||||
else if (__real_pthread_cond_timedwait_2_0)
|
||||
__real_pthread_cond_timedwait = __real_pthread_cond_timedwait_2_0;
|
||||
else
|
||||
__real_pthread_cond_timedwait = dlsym (dlflag, "pthread_cond_timedwait");
|
||||
if (__real_pthread_cond_timedwait == NULL)
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_timedwait\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_join", "GLIBC_2.0");
|
||||
if (ptr)
|
||||
__real_pthread_join = (void *) ptr;
|
||||
|
||||
__real_pthread_join_2_34 = dlvsym (dlflag, "pthread_join", "GLIBC_2.34");
|
||||
__real_pthread_join_2_17 = dlvsym (dlflag, "pthread_join", "GLIBC_2.17");
|
||||
__real_pthread_join_2_2_5 = dlvsym (dlflag, "pthread_join", "GLIBC_2.2.5");
|
||||
__real_pthread_join_2_0 = dlvsym (dlflag, "pthread_join", "GLIBC_2.0");
|
||||
if (__real_pthread_join_2_34)
|
||||
__real_pthread_join = __real_pthread_join_2_34;
|
||||
else if (__real_pthread_join_2_17)
|
||||
__real_pthread_join = __real_pthread_join_2_17;
|
||||
else if (__real_pthread_join_2_2_5)
|
||||
__real_pthread_join = __real_pthread_join_2_2_5;
|
||||
else if (__real_pthread_join_2_0)
|
||||
__real_pthread_join = __real_pthread_join_2_0;
|
||||
else
|
||||
__real_pthread_join = dlsym (dlflag, "pthread_join");
|
||||
if (__real_pthread_join == NULL)
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_join\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "sem_wait", "GLIBC_2.1");
|
||||
if (ptr)
|
||||
__real_sem_wait = (void *) ptr;
|
||||
|
||||
__real_sem_wait_2_34 = dlvsym (dlflag, "sem_wait", "GLIBC_2.34");
|
||||
__real_sem_wait_2_17 = dlvsym (dlflag, "sem_wait", "GLIBC_2.17");
|
||||
__real_sem_wait_2_2_5 = dlvsym (dlflag, "sem_wait", "GLIBC_2.2.5");
|
||||
__real_sem_wait_2_1 = dlvsym (dlflag, "sem_wait", "GLIBC_2.1");
|
||||
__real_sem_wait_2_0 = dlvsym (dlflag, "sem_wait", "GLIBC_2.0");
|
||||
if (__real_sem_wait_2_34)
|
||||
__real_sem_wait = __real_sem_wait_2_34;
|
||||
else if (__real_sem_wait_2_17)
|
||||
__real_sem_wait = __real_sem_wait_2_17;
|
||||
else if (__real_sem_wait_2_2_5)
|
||||
__real_sem_wait = __real_sem_wait_2_2_5;
|
||||
else if (__real_sem_wait_2_1)
|
||||
__real_sem_wait = __real_sem_wait_2_1;
|
||||
else if (__real_sem_wait_2_0)
|
||||
__real_sem_wait = __real_sem_wait_2_0;
|
||||
else
|
||||
__real_sem_wait = dlsym (dlflag, "sem_wait");
|
||||
if (__real_sem_wait == NULL)
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT sem_wait\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
|
||||
#if ARCH(Intel)
|
||||
/* ############## Intel specific additional pointers for 32-bits */
|
||||
ptr = __real_sem_wait_2_1 = __real_sem_wait;
|
||||
ptr = dlvsym (dlflag, "sem_wait", "GLIBC_2.0");
|
||||
if (ptr)
|
||||
__real_sem_wait_2_0 = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT sem_wait_2_0\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.0");
|
||||
if (ptr)
|
||||
__real_pthread_cond_wait_2_0 = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_wait_2_0\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.0");
|
||||
if (ptr)
|
||||
__real_pthread_cond_timedwait_2_0 = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT __real_pthread_cond_timedwait_2_0\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
#endif /* ARCH(Intel) */
|
||||
|
||||
#else /* WSIZE(64) */
|
||||
/* # most versions are different between platforms */
|
||||
/* # the few that are common are set after the ARCH ifdef */
|
||||
#if ARCH(Aarch64)
|
||||
dlflag = RTLD_NEXT;
|
||||
#define GLIBC_N "GLIBC_2.17"
|
||||
__real_pthread_mutex_lock = dlvsym(dlflag, "pthread_mutex_lock", GLIBC_N);
|
||||
__real_pthread_mutex_unlock = dlvsym(dlflag, "pthread_mutex_unlock", GLIBC_N);
|
||||
__real_pthread_cond_wait = dlvsym(dlflag, "pthread_cond_wait", GLIBC_N);
|
||||
__real_pthread_cond_timedwait = dlvsym(dlflag, "pthread_cond_timedwait", GLIBC_N);
|
||||
__real_pthread_join = dlvsym(dlflag, "pthread_join", GLIBC_N);
|
||||
__real_sem_wait = dlvsym(dlflag, "sem_wait", GLIBC_N);
|
||||
|
||||
#elif ARCH(Intel)
|
||||
dlflag = RTLD_NEXT;
|
||||
ptr = dlvsym (dlflag, "pthread_mutex_lock", "GLIBC_2.2.5");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
/* We are probably dlopened after libthread/libc,
|
||||
* try to search in the previously loaded objects
|
||||
*/
|
||||
dlflag = RTLD_DEFAULT;
|
||||
ptr = dlvsym (dlflag, "pthread_mutex_lock", "GLIBC_2.2.5");
|
||||
if (ptr != NULL)
|
||||
{
|
||||
__real_pthread_mutex_lock = ptr;
|
||||
Tprintf (0, "synctrace: WARNING: init_thread_intf() using RTLD_DEFAULT for Solaris sync routines\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_mutex_lock\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
__real_pthread_mutex_lock = ptr;
|
||||
ptr = dlvsym (dlflag, "pthread_mutex_unlock", "GLIBC_2.2.5");
|
||||
if (ptr)
|
||||
__real_pthread_mutex_unlock = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_mutex_unlock\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.3.2");
|
||||
if (ptr)
|
||||
__real_pthread_cond_wait = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_wait\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.3.2");
|
||||
if (ptr)
|
||||
__real_pthread_cond_timedwait = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_timedwait\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_join", "GLIBC_2.2.5");
|
||||
if (ptr)
|
||||
__real_pthread_join = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_join\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "sem_wait", "GLIBC_2.2.5");
|
||||
if (ptr)
|
||||
__real_sem_wait = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT sem_wait\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.2.5");
|
||||
if (ptr)
|
||||
__real_pthread_cond_wait_2_2_5 = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_wait_2_2_5\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.2.5");
|
||||
if (ptr)
|
||||
__real_pthread_cond_timedwait_2_2_5 = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_timedwait_2_2_5\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
|
||||
#elif ARCH(SPARC)
|
||||
dlflag = RTLD_NEXT;
|
||||
ptr = dlvsym (dlflag, "pthread_mutex_lock", "GLIBC_2.2");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
/* We are probably dlopened after libthread/libc,
|
||||
* try to search in the previously loaded objects
|
||||
*/
|
||||
dlflag = RTLD_DEFAULT;
|
||||
ptr = dlvsym (dlflag, "pthread_mutex_lock", "GLIBC_2.2");
|
||||
if (ptr != NULL)
|
||||
{
|
||||
__real_pthread_mutex_lock = ptr;
|
||||
Tprintf (0, "synctrace: WARNING: init_thread_intf() using RTLD_DEFAULT for Solaris sync routines\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT mutex_lock\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
__real_pthread_mutex_lock = ptr;
|
||||
ptr = dlvsym (dlflag, "pthread_mutex_unlock", "GLIBC_2.2");
|
||||
if (ptr)
|
||||
__real_pthread_mutex_unlock = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_mutex_unlock\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.3.2");
|
||||
if (ptr)
|
||||
__real_pthread_cond_wait = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_wait\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.3.2");
|
||||
if (ptr)
|
||||
__real_pthread_cond_timedwait = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_timedwait\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_join", "GLIBC_2.2");
|
||||
if (ptr)
|
||||
__real_pthread_join = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_join\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "sem_wait", "GLIBC_2.2");
|
||||
if (ptr)
|
||||
__real_sem_wait = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT sem_wait\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_wait", "GLIBC_2.2");
|
||||
if (ptr)
|
||||
__real_pthread_cond_wait_2_2 = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_wait_2_2_5\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
ptr = dlvsym (dlflag, "pthread_cond_timedwait", "GLIBC_2.2");
|
||||
if (ptr)
|
||||
__real_pthread_cond_timedwait_2_2 = (void *) ptr;
|
||||
else
|
||||
{
|
||||
CALL_REAL (fprintf)(stderr, "synctrace_init COL_ERROR_SYNCINIT pthread_cond_timedwait_2_2\n");
|
||||
err = COL_ERROR_SYNCINIT;
|
||||
}
|
||||
#endif /* ARCH() */
|
||||
#endif /* WSIZE(64) */
|
||||
/* the pointers that are common to 32- and 64-bits, and to SPARC and Intel */
|
||||
|
||||
__real_pthread_cond_wait_2_3_2 = __real_pthread_cond_wait;
|
||||
__real_pthread_cond_timedwait_2_3_2 = __real_pthread_cond_timedwait;
|
||||
ptr = dlsym (dlflag, "strtol");
|
||||
if (ptr)
|
||||
__real_strtol = (void *) ptr;
|
||||
@ -703,25 +567,24 @@ __collector_jsync_end (hrtime_t reqt, void *object)
|
||||
spacket.comm.tstamp = grnt;
|
||||
spacket.requested = reqt;
|
||||
spacket.objp = (intptr_t) object;
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl, spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) & spacket);
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl,
|
||||
spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) &spacket);
|
||||
}
|
||||
Tprintf (DBG_LT1, "__collector_jsync_begin: end event\n");
|
||||
POP_REENTRANCE (guard);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------- pthread_mutex_lock */
|
||||
int
|
||||
pthread_mutex_lock (pthread_mutex_t *mp)
|
||||
static int
|
||||
gprofng_pthread_mutex_lock (int (real_func) (pthread_mutex_t *),
|
||||
pthread_mutex_t *mp)
|
||||
{
|
||||
int *guard;
|
||||
if (NULL_PTR (pthread_mutex_lock))
|
||||
init_thread_intf ();
|
||||
if (CHCK_NREENTRANCE (guard))
|
||||
return CALL_REAL (pthread_mutex_lock)(mp);
|
||||
return (real_func) (mp);
|
||||
PUSH_REENTRANCE (guard);
|
||||
hrtime_t reqt = gethrtime ();
|
||||
int ret = CALL_REAL (pthread_mutex_lock)(mp);
|
||||
int ret = (real_func) (mp);
|
||||
if (RECHCK_NREENTRANCE (guard))
|
||||
{
|
||||
POP_REENTRANCE (guard);
|
||||
@ -736,83 +599,39 @@ pthread_mutex_lock (pthread_mutex_t *mp)
|
||||
spacket.comm.tstamp = grnt;
|
||||
spacket.requested = reqt;
|
||||
spacket.objp = (intptr_t) mp;
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl, spacket.comm.tstamp, FRINFO_FROM_STACK, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) & spacket);
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl,
|
||||
spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) &spacket);
|
||||
}
|
||||
POP_REENTRANCE (guard);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DCL_PTHREAD_MUTEX_LOCK(dcl_f, real_f) \
|
||||
int dcl_f (pthread_mutex_t *mp) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_thread_intf (); \
|
||||
return gprofng_pthread_mutex_lock (real_f, mp); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_PTHREAD_MUTEX_LOCK, pthread_mutex_lock_2_17, timer_create@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_MUTEX_LOCK, pthread_mutex_lock_2_2_5, timer_create@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_MUTEX_LOCK, pthread_mutex_lock_2_0, timer_create@GLIBC_2.0)
|
||||
DCL_PTHREAD_MUTEX_LOCK (pthread_mutex_lock, CALL_REAL (pthread_mutex_lock))
|
||||
|
||||
/*------------------------------------------------------------- pthread_cond_wait */
|
||||
// map interposed symbol versions
|
||||
static int
|
||||
__collector_pthread_cond_wait_symver (int(real_pthread_cond_wait) (), pthread_cond_t *cond, pthread_mutex_t *mutex);
|
||||
|
||||
#if ARCH(Intel) || ARCH(SPARC)
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_cond_wait_2_3_2,
|
||||
pthread_cond_wait@GLIBC_2.3.2)
|
||||
#endif
|
||||
int
|
||||
__collector_pthread_cond_wait_2_3_2 (pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
if (NULL_PTR (pthread_cond_wait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_pthread_cond_wait_2_3_2@%p\n", CALL_REAL (pthread_cond_wait_2_3_2));
|
||||
return __collector_pthread_cond_wait_symver (CALL_REAL (pthread_cond_wait_2_3_2), cond, mutex);
|
||||
}
|
||||
|
||||
#if WSIZE(32)
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_cond_wait_2_0,
|
||||
pthread_cond_wait@GLIBC_2.0)
|
||||
int
|
||||
__collector_pthread_cond_wait_2_0 (pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
if (NULL_PTR (pthread_cond_wait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_pthread_cond_wait_2_0@%p\n", CALL_REAL (pthread_cond_wait_2_0));
|
||||
return __collector_pthread_cond_wait_symver (CALL_REAL (pthread_cond_wait_2_0), cond, mutex);
|
||||
}
|
||||
#else // WSIZE(64)
|
||||
#if ARCH(Intel)
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_cond_wait_2_2_5,
|
||||
pthread_cond_wait@GLIBC_2.2.5)
|
||||
int
|
||||
__collector_pthread_cond_wait_2_2_5 (pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
if (NULL_PTR (pthread_cond_wait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_pthread_cond_wait_2_2_5@%p\n", CALL_REAL (pthread_cond_wait_2_2_5));
|
||||
return __collector_pthread_cond_wait_symver (CALL_REAL (pthread_cond_wait_2_2_5), cond, mutex);
|
||||
}
|
||||
#elif ARCH(SPARC)
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_cond_wait_2_2,
|
||||
pthread_cond_wait@GLIBC_2.2)
|
||||
int
|
||||
__collector_pthread_cond_wait_2_2 (pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
if (NULL_PTR (pthread_cond_wait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_pthread_cond_wait_2_2@%p\n", CALL_REAL (pthread_cond_wait_2_2));
|
||||
return __collector_pthread_cond_wait_symver (CALL_REAL (pthread_cond_wait_2_2), cond, mutex);
|
||||
}
|
||||
#endif // ARCH()
|
||||
#endif // WSIZE()
|
||||
|
||||
static int
|
||||
__collector_pthread_cond_wait_symver (int(real_pthread_cond_wait) (), pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
gprofng_pthread_cond_wait (int(real_func) (pthread_cond_t *, pthread_mutex_t *),
|
||||
pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
int *guard;
|
||||
if (NULL_PTR (pthread_cond_wait))
|
||||
init_thread_intf ();
|
||||
if (CHCK_NREENTRANCE (guard))
|
||||
return (real_pthread_cond_wait) (cond, mutex);
|
||||
return (real_func) (cond, mutex);
|
||||
PUSH_REENTRANCE (guard);
|
||||
hrtime_t reqt = gethrtime ();
|
||||
int ret = -1;
|
||||
ret = (real_pthread_cond_wait) (cond, mutex);
|
||||
ret = (real_func) (cond, mutex);
|
||||
if (RECHCK_NREENTRANCE (guard))
|
||||
{
|
||||
POP_REENTRANCE (guard);
|
||||
@ -827,95 +646,42 @@ __collector_pthread_cond_wait_symver (int(real_pthread_cond_wait) (), pthread_co
|
||||
spacket.comm.tstamp = grnt;
|
||||
spacket.requested = reqt;
|
||||
spacket.objp = (intptr_t) mutex;
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl, spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) & spacket);
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl,
|
||||
spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) &spacket);
|
||||
}
|
||||
POP_REENTRANCE (guard);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DCL_PTHREAD_COND_WAIT(dcl_f, real_f) \
|
||||
int dcl_f (pthread_cond_t *cond, pthread_mutex_t *mutex) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_thread_intf (); \
|
||||
return gprofng_pthread_cond_wait (real_f, cond, mutex); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_PTHREAD_COND_WAIT, pthread_cond_wait_2_17, pthread_cond_wait@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_COND_WAIT, pthread_cond_wait_2_3_2, pthread_cond_wait@GLIBC_2.3.2)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_COND_WAIT, pthread_cond_wait_2_2_5, pthread_cond_wait@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_COND_WAIT, pthread_cond_wait_2_0, pthread_cond_wait@GLIBC_2.0)
|
||||
DCL_PTHREAD_COND_WAIT (pthread_cond_wait, CALL_REAL (pthread_cond_wait))
|
||||
|
||||
/*---------------------------------------------------- pthread_cond_timedwait */
|
||||
// map interposed symbol versions
|
||||
static int
|
||||
__collector_pthread_cond_timedwait_symver (int(real_pthread_cond_timedwait) (),
|
||||
pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime);
|
||||
|
||||
#if ARCH(Intel) || ARCH(SPARC)
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_cond_timedwait_2_3_2,
|
||||
pthread_cond_timedwait@GLIBC_2.3.2)
|
||||
#endif // ARCH()
|
||||
int
|
||||
__collector_pthread_cond_timedwait_2_3_2 (pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
if (NULL_PTR (pthread_cond_timedwait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_pthread_cond_timedwait_2_3_2@%p\n", CALL_REAL (pthread_cond_timedwait_2_3_2));
|
||||
return __collector_pthread_cond_timedwait_symver (CALL_REAL (pthread_cond_timedwait_2_3_2), cond, mutex, abstime);
|
||||
}
|
||||
|
||||
#if WSIZE(32)
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_cond_timedwait_2_0,
|
||||
pthread_cond_timedwait@GLIBC_2.0)
|
||||
int
|
||||
__collector_pthread_cond_timedwait_2_0 (pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
if (NULL_PTR (pthread_cond_timedwait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_pthread_cond_timedwait_2_0@%p\n", CALL_REAL (pthread_cond_timedwait_2_0));
|
||||
return __collector_pthread_cond_timedwait_symver (CALL_REAL (pthread_cond_timedwait_2_0), cond, mutex, abstime);
|
||||
}
|
||||
#else // WSIZE(64)
|
||||
#if ARCH(Intel)
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_cond_timedwait_2_2_5,
|
||||
pthread_cond_timedwait@GLIBC_2.2.5)
|
||||
int
|
||||
__collector_pthread_cond_timedwait_2_2_5 (pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
if (NULL_PTR (pthread_cond_timedwait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_pthread_cond_timedwait_2_2_5@%p\n", CALL_REAL (pthread_cond_timedwait_2_2_5));
|
||||
return __collector_pthread_cond_timedwait_symver (CALL_REAL (pthread_cond_timedwait_2_2_5), cond, mutex, abstime);
|
||||
}
|
||||
#elif ARCH(SPARC)
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_pthread_cond_timedwait_2_2,
|
||||
pthread_cond_timedwait@GLIBC_2.2)
|
||||
int
|
||||
__collector_pthread_cond_timedwait_2_2 (pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
if (NULL_PTR (pthread_cond_timedwait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_pthread_cond_timedwait_2_2@%p\n", CALL_REAL (pthread_cond_timedwait_2_2));
|
||||
return __collector_pthread_cond_timedwait_symver (CALL_REAL (pthread_cond_timedwait_2_2), cond, mutex, abstime);
|
||||
}
|
||||
#endif // ARCH()
|
||||
#endif // WSIZE()
|
||||
|
||||
static int
|
||||
__collector_pthread_cond_timedwait_symver (int(real_pthread_cond_timedwait) (),
|
||||
pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
gprofng_pthread_cond_timedwait (int(real_func) (pthread_cond_t *,
|
||||
pthread_mutex_t*, const struct timespec *),
|
||||
pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
int *guard;
|
||||
if (NULL_PTR (pthread_cond_timedwait))
|
||||
init_thread_intf ();
|
||||
if (CHCK_NREENTRANCE (guard))
|
||||
return (real_pthread_cond_timedwait) (cond, mutex, abstime);
|
||||
return (real_func) (cond, mutex, abstime);
|
||||
PUSH_REENTRANCE (guard);
|
||||
hrtime_t reqt = gethrtime ();
|
||||
int ret = -1;
|
||||
ret = (real_pthread_cond_timedwait) (cond, mutex, abstime);
|
||||
ret = (real_func) (cond, mutex, abstime);
|
||||
if (RECHCK_NREENTRANCE (guard))
|
||||
{
|
||||
POP_REENTRANCE (guard);
|
||||
@ -925,30 +691,46 @@ __collector_pthread_cond_timedwait_symver (int(real_pthread_cond_timedwait) (),
|
||||
if (grnt - reqt >= sync_threshold)
|
||||
{
|
||||
Sync_packet spacket;
|
||||
collector_memset (&spacket, 0, sizeof ( Sync_packet));
|
||||
spacket.comm.tsize = sizeof ( Sync_packet);
|
||||
collector_memset (&spacket, 0, sizeof (Sync_packet));
|
||||
spacket.comm.tsize = sizeof (Sync_packet);
|
||||
spacket.comm.tstamp = grnt;
|
||||
spacket.requested = reqt;
|
||||
spacket.objp = (intptr_t) mutex;
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl, spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) & spacket);
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl,
|
||||
spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) &spacket);
|
||||
}
|
||||
POP_REENTRANCE (guard);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DCL_PTHREAD_COND_TIMEDWAIT(dcl_f, real_f) \
|
||||
int dcl_f (pthread_cond_t *cond, pthread_mutex_t *mutex, \
|
||||
const struct timespec *abstime) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_thread_intf (); \
|
||||
return gprofng_pthread_cond_timedwait (real_f, cond, mutex, abstime); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_PTHREAD_COND_TIMEDWAIT, pthread_cond_timedwait_2_17, pthread_cond_timedwait@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_COND_TIMEDWAIT, pthread_cond_timedwait_2_3_2, pthread_cond_timedwait@GLIBC_2.3.2)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_COND_TIMEDWAIT, pthread_cond_timedwait_2_2_5, pthread_cond_timedwait@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_COND_TIMEDWAIT, pthread_cond_timedwait_2_0, pthread_cond_timedwait@GLIBC_2.0)
|
||||
DCL_PTHREAD_COND_TIMEDWAIT (pthread_cond_timedwait, CALL_REAL (pthread_cond_timedwait))
|
||||
|
||||
|
||||
/*------------------------------------------------------------- pthread_join */
|
||||
int
|
||||
pthread_join (pthread_t target_thread, void **status)
|
||||
static int
|
||||
gprofng_pthread_join (int(real_func) (pthread_t, void **),
|
||||
pthread_t target_thread, void **status)
|
||||
{
|
||||
int *guard;
|
||||
if (NULL_PTR (pthread_join))
|
||||
init_thread_intf ();
|
||||
if (CHCK_NREENTRANCE (guard))
|
||||
return CALL_REAL (pthread_join)(target_thread, status);
|
||||
return real_func (target_thread, status);
|
||||
PUSH_REENTRANCE (guard);
|
||||
hrtime_t reqt = gethrtime ();
|
||||
int ret = CALL_REAL (pthread_join)(target_thread, status);
|
||||
int ret = real_func(target_thread, status);
|
||||
if (RECHCK_NREENTRANCE (guard))
|
||||
{
|
||||
POP_REENTRANCE (guard);
|
||||
@ -958,73 +740,44 @@ pthread_join (pthread_t target_thread, void **status)
|
||||
if (grnt - reqt >= sync_threshold)
|
||||
{
|
||||
Sync_packet spacket;
|
||||
collector_memset (&spacket, 0, sizeof ( Sync_packet));
|
||||
spacket.comm.tsize = sizeof ( Sync_packet);
|
||||
collector_memset (&spacket, 0, sizeof (Sync_packet));
|
||||
spacket.comm.tsize = sizeof (Sync_packet);
|
||||
spacket.comm.tstamp = grnt;
|
||||
spacket.requested = reqt;
|
||||
spacket.objp = (Vaddr_type) target_thread;
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl, spacket.comm.tstamp, FRINFO_FROM_STACK, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) & spacket);
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl,
|
||||
spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) &spacket);
|
||||
}
|
||||
POP_REENTRANCE (guard);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DCL_PTHREAD_JOIN(dcl_f, real_f) \
|
||||
int dcl_f (pthread_t target_thread, void **status) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_thread_intf (); \
|
||||
return gprofng_pthread_join (real_f, target_thread, status); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_PTHREAD_JOIN, pthread_join_2_34, pthread_join@GLIBC_2.34)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_JOIN, pthread_join_2_17, pthread_join@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_JOIN, pthread_join_2_2_5, pthread_join@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_PTHREAD_JOIN, pthread_join_2_0, pthread_join@GLIBC_2.0)
|
||||
DCL_PTHREAD_JOIN (pthread_join, CALL_REAL (pthread_join))
|
||||
|
||||
/*------------------------------------------------------------- sem_wait */
|
||||
// map interposed symbol versions
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
static int
|
||||
__collector_sem_wait_symver (int(real_sem_wait) (), sem_t *sp);
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_sem_wait_2_1, sem_wait@GLIBC_2.1)
|
||||
int
|
||||
__collector_sem_wait_2_1 (sem_t *sp)
|
||||
gprofng_sem_wait (int (real_func) (sem_t *), sem_t *sp)
|
||||
{
|
||||
if (NULL_PTR (sem_wait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_sem_wait_2_1@%p\n", CALL_REAL (sem_wait_2_1));
|
||||
return __collector_sem_wait_symver (CALL_REAL (sem_wait_2_1), sp);
|
||||
}
|
||||
|
||||
SYMVER_ATTRIBUTE (__collector_sem_wait_2_0, sem_wait@GLIBC_2.0)
|
||||
int
|
||||
__collector_sem_wait_2_0 (sem_t *sp)
|
||||
{
|
||||
if (NULL_PTR (sem_wait))
|
||||
init_thread_intf ();
|
||||
TprintfT (DBG_LTT, "linetrace: GLIBC: __collector_sem_wait_2_0@%p\n", CALL_REAL (sem_wait_2_0));
|
||||
return __collector_sem_wait_symver (CALL_REAL (sem_wait_2_0), sp);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
static int
|
||||
__collector_sem_wait_symver (int(real_sem_wait) (), sem_t *sp)
|
||||
{
|
||||
#else
|
||||
int
|
||||
sem_wait (sem_t *sp)
|
||||
{
|
||||
#endif
|
||||
int *guard;
|
||||
if (NULL_PTR (sem_wait))
|
||||
init_thread_intf ();
|
||||
if (CHCK_NREENTRANCE (guard))
|
||||
{
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
return (real_sem_wait) (sp);
|
||||
#else
|
||||
return CALL_REAL (sem_wait)(sp);
|
||||
#endif
|
||||
}
|
||||
return real_func (sp);
|
||||
PUSH_REENTRANCE (guard);
|
||||
hrtime_t reqt = gethrtime ();
|
||||
int ret = -1;
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
ret = (real_sem_wait) (sp);
|
||||
#else
|
||||
ret = CALL_REAL (sem_wait)(sp);
|
||||
#endif
|
||||
ret = real_func (sp);
|
||||
if (RECHCK_NREENTRANCE (guard))
|
||||
{
|
||||
POP_REENTRANCE (guard);
|
||||
@ -1034,19 +787,30 @@ sem_wait (sem_t *sp)
|
||||
if (grnt - reqt >= sync_threshold)
|
||||
{
|
||||
Sync_packet spacket;
|
||||
collector_memset (&spacket, 0, sizeof ( Sync_packet));
|
||||
spacket.comm.tsize = sizeof ( Sync_packet);
|
||||
collector_memset (&spacket, 0, sizeof (Sync_packet));
|
||||
spacket.comm.tsize = sizeof (Sync_packet);
|
||||
spacket.comm.tstamp = grnt;
|
||||
spacket.requested = reqt;
|
||||
spacket.objp = (intptr_t) sp;
|
||||
|
||||
#if ARCH(Intel) && WSIZE(32)
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl, spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
#else
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl, spacket.comm.tstamp, FRINFO_FROM_STACK, &spacket);
|
||||
#endif
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) & spacket);
|
||||
spacket.comm.frinfo = collector_interface->getFrameInfo (sync_hndl,
|
||||
spacket.comm.tstamp, FRINFO_FROM_STACK_ARG, &spacket);
|
||||
collector_interface->writeDataRecord (sync_hndl, (Common_packet*) &spacket);
|
||||
}
|
||||
POP_REENTRANCE (guard);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DCL_SEM_WAIT(dcl_f, real_f) \
|
||||
int dcl_f (sem_t *sp) \
|
||||
{ \
|
||||
if ((real_f) == NULL) \
|
||||
init_thread_intf (); \
|
||||
return gprofng_sem_wait (real_f, sp); \
|
||||
}
|
||||
|
||||
DCL_FUNC_VER (DCL_SEM_WAIT, sem_wait_2_34, sem_wait@GLIBC_2.34)
|
||||
DCL_FUNC_VER (DCL_SEM_WAIT, sem_wait_2_17, sem_wait@GLIBC_2.17)
|
||||
DCL_FUNC_VER (DCL_SEM_WAIT, sem_wait_2_2_5, sem_wait@GLIBC_2.2.5)
|
||||
DCL_FUNC_VER (DCL_SEM_WAIT, sem_wait_2_0, sem_wait@GLIBC_2.0)
|
||||
DCL_FUNC_VER (DCL_SEM_WAIT, sem_wait_2_1, sem_wait@GLIBC_2.1)
|
||||
DCL_SEM_WAIT (sem_wait, CALL_REAL (sem_wait))
|
||||
|
@ -222,15 +222,4 @@ extern "C"
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __has_attribute
|
||||
# if __has_attribute (__symver__)
|
||||
# define SYMVER_ATTRIBUTE(sym, symver) \
|
||||
__attribute__ ((__symver__ (#symver)))
|
||||
# endif
|
||||
#endif
|
||||
#ifndef SYMVER_ATTRIBUTE
|
||||
# define SYMVER_ATTRIBUTE(sym, symver) \
|
||||
__asm__(".symver " #sym "," #symver);
|
||||
#endif
|
||||
|
||||
#endif /* _COLLECTOR_MODULE_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user