aboutsummaryrefslogtreecommitdiff
path: root/gprofng/libcollector/linetrace.c
diff options
context:
space:
mode:
authorVladimir Mezentsev <vladimir.mezentsev@oracle.com>2023-04-16 13:55:48 -0700
committerVladimir Mezentsev <vladimir.mezentsev@oracle.com>2023-04-17 13:01:38 -0700
commit35fab451d9ec11a7e02df750fb24feb21e9732b8 (patch)
tree64f9f7b28c6ac6a1a300ad29e2c1455ec952333d /gprofng/libcollector/linetrace.c
parent7a515757db9681e86926b7068b3a4a6a2df70299 (diff)
downloadfsf-binutils-gdb-35fab451d9ec11a7e02df750fb24feb21e9732b8.zip
fsf-binutils-gdb-35fab451d9ec11a7e02df750fb24feb21e9732b8.tar.gz
fsf-binutils-gdb-35fab451d9ec11a7e02df750fb24feb21e9732b8.tar.bz2
gprofng: 30360 Seg. Fault when application uses std::thread
We interpose a lot of libC functions (dlopen, fork, pthread_create, etc.). Some of these functions have versions. For example, % nm -D /lib64/gprofng/libgp-collector.so | grep thread_create@ | sort 000000000004b420 T pthread_create@GLIBC_2.34 000000000004b490 T pthread_create@GLIBC_2.17 000000000004b500 T pthread_create@GLIBC_2.2.5 000000000004b570 T pthread_create@GLIBC_2.1 000000000004b5e0 T pthread_create@GLIBC_2.0 Our library does not set the default version for symbols. This is correct because we don't know which libC will be used. gcc and g++ links differently the version symbols when the default version is not set. c-linker is using our pthread_create@GLIBC_2.34 and c++-linker is using our pthread_create@GLIBC_2.0 by default. The current implementation of the interposed functions is: If we are in our pthread_create@GLIBC_<NN>, we use dlvsym (dlflag, "pthread_create", "GLIBC_<NN>") to find and call the same function from libC. In the test from PR 30360, pthread_create@GLIBC_2.0 is not in the current libC. We need to call the default version symbol from libC. gprofng/ChangeLog 2023-04-16 Vladimir Mezentsev <vladimir.mezentsev@oracle.com> PR gprofng/30360 * libcollector/iotrace.c: Find and call a default libC version symbol. * libcollector/dispatcher.c: Likewise. * libcollector/iotrace.c: Likewise. * libcollector/linetrace.c: Likewise. * libcollector/mmaptrace.c: Likewise. * libcollector/synctrace.c: Likewise. * libcollector/collector.h (REAL_DCL): Remove an unused argument.
Diffstat (limited to 'gprofng/libcollector/linetrace.c')
-rw-r--r--gprofng/libcollector/linetrace.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/gprofng/libcollector/linetrace.c b/gprofng/libcollector/linetrace.c
index b29e0b9..917bc95 100644
--- a/gprofng/libcollector/linetrace.c
+++ b/gprofng/libcollector/linetrace.c
@@ -682,8 +682,6 @@ init_lineage_intf ()
__real_execlp = dlsym (dlflag, "execlp");
__real_execl = dlsym (dlflag, "execl");
__real_clone = dlsym (dlflag, "clone");
- __real_posix_spawn = dlsym (dlflag, "posix_spawn");
- __real_posix_spawnp = dlsym (dlflag, "posix_spawnp");
__real_popen_2_17 = dlvsym (dlflag, "popen", "GLIBC_2.17");
__real_popen_2_2_5 = dlvsym (dlflag, "popen", "GLIBC_2.2.5");
@@ -704,11 +702,31 @@ init_lineage_intf ()
__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");
+ if (__real_posix_spawn_2_17)
+ __real_posix_spawn = __real_posix_spawn_2_17;
+ else if (__real_posix_spawn_2_15)
+ __real_posix_spawn = __real_posix_spawn_2_15;
+ else if (__real_posix_spawn_2_2_5)
+ __real_posix_spawn = __real_posix_spawn_2_2_5;
+ else if (__real_posix_spawn_2_2)
+ __real_posix_spawn = __real_posix_spawn_2_2;
+ else
+ __real_posix_spawn = dlsym (dlflag, "posix_spawn");
__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");
__real_posix_spawnp_2_2 = dlvsym (dlflag, "posix_spawnp", "GLIBC_2.2");
+ if (__real_posix_spawnp_2_17)
+ __real_posix_spawnp = __real_posix_spawnp_2_17;
+ else if (__real_posix_spawnp_2_15)
+ __real_posix_spawnp = __real_posix_spawnp_2_15;
+ else if (__real_posix_spawnp_2_2_5)
+ __real_posix_spawnp = __real_posix_spawnp_2_2_5;
+ else if (__real_posix_spawnp_2_2)
+ __real_posix_spawnp = __real_posix_spawnp_2_2;
+ else
+ __real_posix_spawnp = dlsym (dlflag, "posix_spawnp");
__real_grantpt = dlsym (dlflag, "grantpt");
__real_ptsname = dlsym (dlflag, "ptsname");
@@ -1427,16 +1445,16 @@ gprofng_posix_spawn (int(real_posix_spawn) (),
return ret;
}
-#define DCL_POSIX_SPAWN(dcl_f, real_f) \
+#define DCL_POSIX_SPAWN(dcl_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) \
+ if (__real_posix_spawn == NULL) \
init_lineage_intf (); \
- return gprofng_posix_spawn (real_f, pidp, path, file_actions, attrp, \
- argv, envp); \
+ return gprofng_posix_spawn (__real_posix_spawn, pidp, path, file_actions, \
+ attrp, argv, envp); \
}
@@ -1444,7 +1462,7 @@ 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))
+DCL_POSIX_SPAWN (posix_spawn)
/*-------------------------------------------------------- posix_spawnp */
static int
@@ -1484,15 +1502,15 @@ gprofng_posix_spawnp (int (real_posix_spawnp) (),
return ret;
}
-#define DCL_POSIX_SPAWNP(dcl_f, real_f) \
+#define DCL_POSIX_SPAWNP(dcl_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) \
+ if (__real_posix_spawnp == NULL) \
init_lineage_intf (); \
- return gprofng_posix_spawnp (real_f, pidp, path, \
+ return gprofng_posix_spawnp (__real_posix_spawnp, pidp, path, \
file_actions, attrp, argv, envp); \
}
@@ -1500,7 +1518,7 @@ 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))
+DCL_POSIX_SPAWNP (posix_spawnp)
/*------------------------------------------------------------- system */
int system () __attribute__ ((weak, alias ("__collector_system")));
@@ -1529,10 +1547,10 @@ __collector_system (const char *cmd)
/*------------------------------------------------------------- popen */
// map interposed symbol versions
-#define DCL_POPEN(dcl_f, real_f) \
+#define DCL_POPEN(dcl_f) \
FILE *dcl_f (const char *cmd, const char *mode) \
{ \
- if ((real_f) == NULL) \
+ if (__real_popen == 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 ()); \
@@ -1540,11 +1558,11 @@ __collector_system (const char *cmd)
if (line_mode == LM_TRACK_LINEAGE) \
INIT_REENTRANCE (guard); \
if (guard == NULL) \
- return (real_f) (cmd, mode); \
+ return __real_popen (cmd, mode); \
int following_combo = 0; \
linetrace_ext_combo_prologue ("popen", cmd, &following_combo); \
PUSH_REENTRANCE (guard); \
- FILE *ret = (real_f) (cmd, mode); \
+ FILE *ret = __real_popen (cmd, mode); \
POP_REENTRANCE (guard); \
linetrace_ext_combo_epilogue ("popen", ret == NULL ? -1 : 0, \
&following_combo); \
@@ -1555,7 +1573,7 @@ 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))
+DCL_POPEN (popen)
/*------------------------------------------------------------- grantpt */
int grantpt () __attribute__ ((weak, alias ("__collector_grantpt")));