SUBDIRS = demangle . docs tests
-CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+CFLAGS = $(WERROR) -DVG_LIBDIR="\"$(libdir)"\" \
+ -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
valdir = $(libdir)/valgrind
SUBDIRS = demangle . docs tests
-CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+CFLAGS = $(WERROR) -DVG_LIBDIR="\"$(libdir)"\" \
+ -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
valdir = $(libdir)/valgrind
SUBDIRS = demangle . docs tests
-CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+CFLAGS = $(WERROR) -DVG_LIBDIR="\"$(libdir)"\" \
+ -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
valdir = $(libdir)/valgrind
SUBDIRS = demangle . docs tests
-CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+CFLAGS = $(WERROR) -DVG_LIBDIR="\"$(libdir)"\" \
+ -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
valdir = $(libdir)/valgrind
SUBDIRS = demangle . docs tests
-CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+CFLAGS = $(WERROR) -DVG_LIBDIR="\"$(libdir)"\" \
+ -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
valdir = $(libdir)/valgrind
exit 1
fi
+# A bit subtle. The LD_PRELOAD added entry must be absolute
+# and not depend on LD_LIBRARY_PATH. This is so that we can
+# mess with LD_LIBRARY_PATH for child processes, which makes
+# libpthread.so fall out of visibility, independently of
+# whether valgrind.so is visible.
VG_ARGS="$VALGRIND_OPTS $vgsupp $vgopts"
export VG_ARGS
LD_LIBRARY_PATH=$VALGRIND:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
-LD_PRELOAD=valgrind.so:$LD_PRELOAD
+LD_PRELOAD=$VALGRIND/valgrind.so:$LD_PRELOAD
export LD_PRELOAD
#LD_DEBUG=files
#LD_DEBUG=symbols
extern Bool VG_(stringMatch) ( Char* pat, Char* str );
-#define __STRING(x) #x
+#define VG__STRING(__str) #__str
/* Asserts are permanently enabled. Hurrah! */
#define vg_assert(expr) \
((void) ((expr) ? 0 : \
- (VG_(assert_fail) (__STRING(expr), \
+ (VG_(assert_fail) (VG__STRING(expr), \
__FILE__, __LINE__, \
__PRETTY_FUNCTION__), 0)))
extern Char** VG_(client_envp);
/* Remove valgrind.so from a LD_PRELOAD=... string so child processes
- don't get traced into. */
-extern void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str );
+ don't get traced into. Also mess up $libdir/valgrind so that our
+ libpthread.so disappears from view. */
+void VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) ( Char* ld_preload_str,
+ Char* ld_library_path_str );
/* Something of a function looking for a home ... start up GDB. This
is called from VG_(swizzle_esp_then_start_GDB) and so runs on the
VG_(shutdown_logging)();
- /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
- child processes don't get traced into. Also done on simulated
- execve system call. */
+ /* Remove valgrind.so from a LD_PRELOAD=... string so child
+ processes don't get traced into. Also mess up $libdir/valgrind
+ so that our libpthread.so disappears from view. */
if (!VG_(clo_trace_children)) {
- VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
+ VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH)(
+ VG_(getenv)("LD_PRELOAD"),
+ VG_(getenv)("LD_LIBRARY_PATH")
+ );
}
/* Decide how to exit. This depends on what the scheduler
tracing into child processes. To make this work the build system
also supplies a dummy file, "valgrinq.so".
*/
-void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
+void VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) ( Char* ld_preload_str,
+ Char* ld_library_path_str )
{
Char* p;
- if (ld_preload_str == NULL)
- return;
+ vg_assert(ld_preload_str != NULL);
+ vg_assert(ld_library_path_str != NULL);
+ /* VG_(printf)("%s %s\n", ld_preload_str, ld_library_path_str); */
+ /* in LD_PRELOAD, turn valgrind.so into valgrinq.so. */
p = VG_(strstr)(ld_preload_str, "valgrind.so");
- if (p == NULL)
+
+ if (p == NULL) {
+ /* perhaps already happened? */
+ vg_assert(VG_(strstr)(ld_preload_str, "valgrinq.so") != NULL);
+ vg_assert(VG_(strstr)(ld_library_path_str, "lib/valgrinq") != NULL);
return;
+ }
+
+ vg_assert(p[7] == 'd');
p[7] = 'q';
+
+ /* in LD_LIBRARY_PATH, turn $libdir/valgrind (as configure'd) from
+ .../lib/valgrind .../lib/valgrinq, which doesn't exist,
+ so that our own libpthread.so goes out of scope. */
+ p = VG_(strstr)(ld_library_path_str, VG_LIBDIR);
+ vg_assert(NULL != p);
+ p += VG_(strlen)(VG_LIBDIR);
+ p += VG_(strlen)("/valgrind");
+ p --;
+ vg_assert(p[0] == 'd');
+ p[0] = 'q';
}
+
/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
it to attach to this process. Called if the user requests this
service after an error has been shown, so she can poke around and
SUBDIRS = demangle . docs tests
-CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+CFLAGS = $(WERROR) -DVG_LIBDIR="\"$(libdir)"\" \
+ -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
valdir = $(libdir)/valgrind
SUBDIRS = demangle . docs tests
-CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+CFLAGS = $(WERROR) -DVG_LIBDIR="\"$(libdir)"\" \
+ -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
valdir = $(libdir)/valgrind
SUBDIRS = demangle . docs tests
-CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+CFLAGS = $(WERROR) -DVG_LIBDIR="\"$(libdir)"\" \
+ -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
valdir = $(libdir)/valgrind
SUBDIRS = demangle . docs tests
-CFLAGS = $(WERROR) -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
+CFLAGS = $(WERROR) -DVG_LIBDIR="\"$(libdir)"\" \
+ -Winline -Wall -Wshadow -O -fomit-frame-pointer -g
valdir = $(libdir)/valgrind
exit 1
fi
+# A bit subtle. The LD_PRELOAD added entry must be absolute
+# and not depend on LD_LIBRARY_PATH. This is so that we can
+# mess with LD_LIBRARY_PATH for child processes, which makes
+# libpthread.so fall out of visibility, independently of
+# whether valgrind.so is visible.
VG_ARGS="$VALGRIND_OPTS $vgsupp $vgopts"
export VG_ARGS
LD_LIBRARY_PATH=$VALGRIND:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
-LD_PRELOAD=valgrind.so:$LD_PRELOAD
+LD_PRELOAD=$VALGRIND/valgrind.so:$LD_PRELOAD
export LD_PRELOAD
#LD_DEBUG=files
#LD_DEBUG=symbols
extern Bool VG_(stringMatch) ( Char* pat, Char* str );
-#define __STRING(x) #x
+#define VG__STRING(__str) #__str
/* Asserts are permanently enabled. Hurrah! */
#define vg_assert(expr) \
((void) ((expr) ? 0 : \
- (VG_(assert_fail) (__STRING(expr), \
+ (VG_(assert_fail) (VG__STRING(expr), \
__FILE__, __LINE__, \
__PRETTY_FUNCTION__), 0)))
extern Char** VG_(client_envp);
/* Remove valgrind.so from a LD_PRELOAD=... string so child processes
- don't get traced into. */
-extern void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str );
+ don't get traced into. Also mess up $libdir/valgrind so that our
+ libpthread.so disappears from view. */
+void VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) ( Char* ld_preload_str,
+ Char* ld_library_path_str );
/* Something of a function looking for a home ... start up GDB. This
is called from VG_(swizzle_esp_then_start_GDB) and so runs on the
VG_(shutdown_logging)();
- /* In LD_PRELOAD, convert "valgrind.so" into "valgrinq.so", so that
- child processes don't get traced into. Also done on simulated
- execve system call. */
+ /* Remove valgrind.so from a LD_PRELOAD=... string so child
+ processes don't get traced into. Also mess up $libdir/valgrind
+ so that our libpthread.so disappears from view. */
if (!VG_(clo_trace_children)) {
- VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
+ VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH)(
+ VG_(getenv)("LD_PRELOAD"),
+ VG_(getenv)("LD_LIBRARY_PATH")
+ );
}
/* Decide how to exit. This depends on what the scheduler
tracing into child processes. To make this work the build system
also supplies a dummy file, "valgrinq.so".
*/
-void VG_(mash_LD_PRELOAD_string)( Char* ld_preload_str )
+void VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) ( Char* ld_preload_str,
+ Char* ld_library_path_str )
{
Char* p;
- if (ld_preload_str == NULL)
- return;
+ vg_assert(ld_preload_str != NULL);
+ vg_assert(ld_library_path_str != NULL);
+ /* VG_(printf)("%s %s\n", ld_preload_str, ld_library_path_str); */
+ /* in LD_PRELOAD, turn valgrind.so into valgrinq.so. */
p = VG_(strstr)(ld_preload_str, "valgrind.so");
- if (p == NULL)
+
+ if (p == NULL) {
+ /* perhaps already happened? */
+ vg_assert(VG_(strstr)(ld_preload_str, "valgrinq.so") != NULL);
+ vg_assert(VG_(strstr)(ld_library_path_str, "lib/valgrinq") != NULL);
return;
+ }
+
+ vg_assert(p[7] == 'd');
p[7] = 'q';
+
+ /* in LD_LIBRARY_PATH, turn $libdir/valgrind (as configure'd) from
+ .../lib/valgrind .../lib/valgrinq, which doesn't exist,
+ so that our own libpthread.so goes out of scope. */
+ p = VG_(strstr)(ld_library_path_str, VG_LIBDIR);
+ vg_assert(NULL != p);
+ p += VG_(strlen)(VG_LIBDIR);
+ p += VG_(strlen)("/valgrind");
+ p --;
+ vg_assert(p[0] == 'd');
+ p[0] = 'q';
}
+
/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
it to attach to this process. Called if the user requests this
service after an error has been shown, so she can poke around and
if (!VG_(clo_trace_children)) {
Int i;
Char** envp = (Char**)arg3;
+ Char* ld_preload_str = NULL;
+ Char* ld_library_path_str = NULL;
for (i = 0; envp[i] != NULL; i++) {
- if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0) {
- VG_(mash_LD_PRELOAD_string)(&envp[i][11]);
- }
+ if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0)
+ ld_preload_str = &envp[i][11];
+ if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0)
+ ld_library_path_str = &envp[i][16];
}
+ VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH)(
+ ld_preload_str, ld_library_path_str );
}
KERNEL_DO_SYSCALL(tid,res);
/* Should we still be alive here? Don't think so. */