]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix fork/exec stuff so it works again. We have to mangle LD_LIBRARY_PATH
authorJulian Seward <jseward@acm.org>
Sat, 18 May 2002 13:14:17 +0000 (13:14 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 18 May 2002 13:14:17 +0000 (13:14 +0000)
as well as LD_PRELOAD, so as to make our libpthread.so go out of scope
when a child which we don't want to trace, is exec'd.  Otherwise the
child can wind up being connected to our libpthread.so but not to
valgrind.so, which is an unworkable combination; you have to be connected
to both or neither.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@291

16 files changed:
Makefile.am
addrcheck/Makefile.am
cachegrind/Makefile.am
corecheck/Makefile.am
coregrind/Makefile.am
coregrind/valgrind.in
coregrind/vg_include.h
coregrind/vg_main.c
helgrind/Makefile.am
lackey/Makefile.am
memcheck/Makefile.am
none/Makefile.am
valgrind.in
vg_include.h
vg_main.c
vg_syscall_mem.c

index 257be0bdcfcae9fbc5a8aa8d855d38104e38dac3..03cc0da839992066bf74673bcfbea7784d0f027a 100644 (file)
@@ -1,6 +1,7 @@
 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
 
index 257be0bdcfcae9fbc5a8aa8d855d38104e38dac3..03cc0da839992066bf74673bcfbea7784d0f027a 100644 (file)
@@ -1,6 +1,7 @@
 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
 
index 257be0bdcfcae9fbc5a8aa8d855d38104e38dac3..03cc0da839992066bf74673bcfbea7784d0f027a 100644 (file)
@@ -1,6 +1,7 @@
 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
 
index 257be0bdcfcae9fbc5a8aa8d855d38104e38dac3..03cc0da839992066bf74673bcfbea7784d0f027a 100644 (file)
@@ -1,6 +1,7 @@
 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
 
index 257be0bdcfcae9fbc5a8aa8d855d38104e38dac3..03cc0da839992066bf74673bcfbea7784d0f027a 100644 (file)
@@ -1,6 +1,7 @@
 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
 
index 3d12fe1ed518fa03b68b5654c4f8b4ee05dd2a08..b316a74ea1afb17b16d2c1f514c51de573278bf5 100755 (executable)
@@ -165,12 +165,17 @@ if [ $# = 0 ] || [ z"$dousage" = z1 ]; then
    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
index 7f44dde7d4692c2480479dfd02399fd5614e6542..cdcd1caa3b15d60cccf2184bcfff979a62eb5ca7 100644 (file)
@@ -785,12 +785,12 @@ extern void VG_(strncpy) ( Char* dest, const Char* src, Int ndest );
 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)))
 
@@ -1388,8 +1388,10 @@ extern Char** VG_(client_argv);
 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
index 90477316abd74e8ac871c83ad6c212327e1d0588..ddaf556e2c882fa15026358bb01730b6e1930120 100644 (file)
@@ -1100,11 +1100,14 @@ void VG_(main) ( void )
 
    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
@@ -1162,17 +1165,39 @@ void VG_(oynk) ( Int n )
    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
index 257be0bdcfcae9fbc5a8aa8d855d38104e38dac3..03cc0da839992066bf74673bcfbea7784d0f027a 100644 (file)
@@ -1,6 +1,7 @@
 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
 
index 257be0bdcfcae9fbc5a8aa8d855d38104e38dac3..03cc0da839992066bf74673bcfbea7784d0f027a 100644 (file)
@@ -1,6 +1,7 @@
 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
 
index 257be0bdcfcae9fbc5a8aa8d855d38104e38dac3..03cc0da839992066bf74673bcfbea7784d0f027a 100644 (file)
@@ -1,6 +1,7 @@
 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
 
index 257be0bdcfcae9fbc5a8aa8d855d38104e38dac3..03cc0da839992066bf74673bcfbea7784d0f027a 100644 (file)
@@ -1,6 +1,7 @@
 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
 
index 3d12fe1ed518fa03b68b5654c4f8b4ee05dd2a08..b316a74ea1afb17b16d2c1f514c51de573278bf5 100755 (executable)
@@ -165,12 +165,17 @@ if [ $# = 0 ] || [ z"$dousage" = z1 ]; then
    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
index 7f44dde7d4692c2480479dfd02399fd5614e6542..cdcd1caa3b15d60cccf2184bcfff979a62eb5ca7 100644 (file)
@@ -785,12 +785,12 @@ extern void VG_(strncpy) ( Char* dest, const Char* src, Int ndest );
 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)))
 
@@ -1388,8 +1388,10 @@ extern Char** VG_(client_argv);
 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
index 90477316abd74e8ac871c83ad6c212327e1d0588..ddaf556e2c882fa15026358bb01730b6e1930120 100644 (file)
--- a/vg_main.c
+++ b/vg_main.c
@@ -1100,11 +1100,14 @@ void VG_(main) ( void )
 
    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
@@ -1162,17 +1165,39 @@ void VG_(oynk) ( Int n )
    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
index 1ffac13ad2c5401325b2bda332ca2593d3d5da86..ac681c08e8fec15f095e4a2918aae5ed86c91872 100644 (file)
@@ -824,11 +824,16 @@ void VG_(perform_assumed_nonblocking_syscall) ( ThreadId tid )
          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. */