|
From: Nicholas N. <nj...@ca...> - 2004-08-03 13:08:48
|
CVS commit by nethercote:
Factor out differences between VG_(system) and PRE(execve). Required moving
mash_colon_env() from vg_syscalls.c to vg_mylibc.c. Saved 20 lines of code.
M +4 -6 vg_include.h 1.214
M +98 -30 vg_mylibc.c 1.84
M +5 -91 vg_syscalls.c 1.117
--- valgrind/coregrind/vg_include.h #1.213:1.214
@@ -1097,6 +1097,8 @@ extern Int VG_(connect_via_socket)( UCha
/* Environment manipulations */
-extern Char **VG_(env_setenv) ( Char ***envp, const Char* varname, const Char *val );
+extern Char **VG_(env_setenv) ( Char ***envp, const Char* varname,
+ const Char *val );
extern void VG_(env_unsetenv) ( Char **env, const Char *varname );
+extern void VG_(env_remove_valgrind_env_stuff) ( Char** env );
/* ---------------------------------------------------------------------
@@ -1457,8 +1459,4 @@ extern void VG_(init_preopened_fds) ( vo
extern void VG_(fd_stats) ( void );
-/* Walk through a colon separated list variable, removing entries
- which match pattern. */
-extern void VG_(mash_colon_env)(Char *varp, const Char *pattern);
-
/* ---------------------------------------------------------------------
Exports of vg_transtab.c
--- valgrind/coregrind/vg_mylibc.c #1.83:1.84
@@ -1489,23 +1489,69 @@ Int VG_(setpgid) ( Int pid, Int pgrp )
}
-/* Return -1 if error, else 0. NOTE does not indicate return code of
- child! */
-Int VG_(system) ( Char* cmd )
+/* Walk through a colon-separated environment variable, and remove the
+ entries which match remove_pattern. It slides everything down over
+ the removed entries, and pads the remaining space with '\0'. It
+ modifies the entries in place (in the client address space), but it
+ shouldn't matter too much, since we only do this just before an
+ execve().
+
+ This is also careful to mop up any excess ':'s, since empty strings
+ delimited by ':' are considered to be '.' in a path.
+*/
+static void mash_colon_env(Char *varp, const Char *remove_pattern)
{
- Int pid, res;
- if (cmd == NULL)
- return 1;
- pid = VG_(do_syscall)(__NR_fork);
- if (VG_(is_kerror)(pid))
- return -1;
- if (pid == 0) {
- /* child */
- static Char** envp = NULL;
- Char* argv[4];
+ Char *const start = varp;
+ Char *entry_start = varp;
+ Char *output = varp;
- /* restore the DATA rlimit for the child */
- VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
+ if (varp == NULL)
+ return;
- if (envp == NULL) {
+ while(*varp) {
+ if (*varp == ':') {
+ Char prev;
+ Bool match;
+
+ /* This is a bit subtle: we want to match against the entry
+ we just copied, because it may have overlapped with
+ itself, junking the original. */
+
+ prev = *output;
+ *output = '\0';
+
+ match = VG_(string_match)(remove_pattern, entry_start);
+
+ *output = prev;
+
+ if (match) {
+ output = entry_start;
+ varp++; /* skip ':' after removed entry */
+ } else
+ entry_start = output+1; /* entry starts after ':' */
+ }
+
+ *output++ = *varp++;
+ }
+
+ /* match against the last entry */
+ if (VG_(string_match)(remove_pattern, entry_start)) {
+ output = entry_start;
+ if (output > start) {
+ /* remove trailing ':' */
+ output--;
+ vg_assert(*output == ':');
+ }
+ }
+
+ /* pad out the left-overs with '\0' */
+ while(output < varp)
+ *output++ = '\0';
+}
+
+
+// Removes all the Valgrind-added stuff from the passed environment. Used
+// when starting child processes, so they don't see that added stuff.
+void VG_(env_remove_valgrind_env_stuff)(Char** envp)
+{
Int i;
Char* ld_preload_str = NULL;
@@ -1513,6 +1559,5 @@ Int VG_(system) ( Char* cmd )
Char* buf;
- envp = env_clone(VG_(client_envp));
-
+ // Find LD_* variables
for (i = 0; envp[i] != NULL; i++) {
if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0)
@@ -1524,17 +1569,40 @@ Int VG_(system) ( Char* cmd )
buf = VG_(arena_malloc)(VG_AR_CORE, VG_(strlen)(VG_(libdir)) + 20);
+ // Remove Valgrind-specific entries from LD_*.
VG_(sprintf)(buf, "%s*/vg_inject.so", VG_(libdir));
- VG_(mash_colon_env)(ld_preload_str, buf);
-
+ mash_colon_env(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
- VG_(mash_colon_env)(ld_preload_str, buf);
-
+ mash_colon_env(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*", VG_(libdir));
- VG_(mash_colon_env)(ld_library_path_str, buf);
+ mash_colon_env(ld_library_path_str, buf);
+ // Remove VALGRIND_CLO variable.
VG_(env_unsetenv)(envp, VALGRINDCLO);
+ // XXX if variable becomes empty, remove it completely?
+
VG_(arena_free)(VG_AR_CORE, buf);
- }
+}
+
+/* Return -1 if error, else 0. NOTE does not indicate return code of
+ child! */
+Int VG_(system) ( Char* cmd )
+{
+ Int pid, res;
+ if (cmd == NULL)
+ return 1;
+ pid = VG_(do_syscall)(__NR_fork);
+ if (VG_(is_kerror)(pid))
+ return -1;
+ if (pid == 0) {
+ /* child */
+ static Char** envp = NULL;
+ Char* argv[4];
+
+ /* restore the DATA rlimit for the child */
+ VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
+
+ envp = env_clone(VG_(client_envp));
+ VG_(env_remove_valgrind_env_stuff)( envp );
argv[0] = "/bin/sh";
--- valgrind/coregrind/vg_syscalls.c #1.116:1.117
@@ -154,65 +154,4 @@ static Bool valid_client_addr(Addr start
}
-/* Walk through a colon-separated environment variable, and remove the
- entries which matches file_pattern. It slides everything down over
- the removed entries, and pads the remaining space with '\0'. It
- modifies the entries in place (in the client address space), but it
- shouldn't matter too much, since we only do this just before an
- execve().
-
- This is also careful to mop up any excess ':'s, since empty strings
- delimited by ':' are considered to be '.' in a path.
-*/
-void VG_(mash_colon_env)(Char *varp, const Char *remove_pattern)
-{
- Char *const start = varp;
- Char *entry_start = varp;
- Char *output = varp;
-
- if (varp == NULL)
- return;
-
- while(*varp) {
- if (*varp == ':') {
- Char prev;
- Bool match;
-
- /* This is a bit subtle: we want to match against the entry
- we just copied, because it may have overlapped with
- itself, junking the original. */
-
- prev = *output;
- *output = '\0';
-
- match = VG_(string_match)(remove_pattern, entry_start);
-
- *output = prev;
-
- if (match) {
- output = entry_start;
- varp++; /* skip ':' after removed entry */
- } else
- entry_start = output+1; /* entry starts after ':' */
- }
-
- *output++ = *varp++;
- }
-
- /* match against the last entry */
- if (VG_(string_match)(remove_pattern, entry_start)) {
- output = entry_start;
- if (output > start) {
- /* remove trailing ':' */
- output--;
- vg_assert(*output == ':');
- }
- }
-
- /* pad out the left-overs with '\0' */
- while(output < varp)
- *output++ = '\0';
-}
-
-
/* ---------------------------------------------------------------------
Doing mmap, mremap
@@ -1840,37 +1779,12 @@ PRE(execve)
{
- /* Make the LD_LIBRARY_PATH/LD_PRELOAD disappear so that the
- child doesn't get our libpthread and other stuff. This is
- done unconditionally, since if we are tracing the child,
- stage1/2 will set up the appropriate client environment. */
- Int i;
+ // Remove the valgrind-specific stuff from the environment so the
+ // child doesn't get our libpthread and other stuff. This is
+ // done unconditionally, since if we are tracing the child,
+ // stage1/2 will set up the appropriate client environment.
Char** envp = (Char**)arg3;
- Char* ld_preload_str = NULL;
- Char* ld_library_path_str = NULL;
if (envp != NULL) {
- Char *buf;
-
- for (i = 0; envp[i] != NULL; i++) {
- 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];
- }
-
- buf = VG_(arena_malloc)(VG_AR_CORE, VG_(strlen)(VG_(libdir)) + 20);
-
- VG_(sprintf)(buf, "%s*/vg_inject.so", VG_(libdir));
- VG_(mash_colon_env)(ld_preload_str, buf);
-
- VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
- VG_(mash_colon_env)(ld_preload_str, buf);
-
- VG_(sprintf)(buf, "%s*", VG_(libdir));
- VG_(mash_colon_env)(ld_library_path_str, buf);
-
- VG_(env_unsetenv)(envp, VALGRINDCLO);
-
- /* XXX if variable becomes empty, remove it completely? */
+ VG_(env_remove_valgrind_env_stuff)( envp );
}
}
|