From: Nicholas Nethercote Date: Tue, 3 Aug 2004 13:08:31 +0000 (+0000) Subject: Factor out differences between VG_(system) and PRE(execve). Required moving X-Git-Tag: svn/VALGRIND_2_2_0~82 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bdbf7377fe2bf6a899c615854cbdd065606dd1c;p=thirdparty%2Fvalgrind.git 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. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2554 --- diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index f2ba333e81..a39184fd23 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -1096,8 +1096,10 @@ extern Int VG_(write_socket)( Int sd, void *msg, Int count ); extern Int VG_(connect_via_socket)( UChar* str ); /* Environment manipulations */ -extern Char **VG_(env_setenv) ( Char ***envp, const Char* varname, const Char *val ); -extern void VG_(env_unsetenv) ( Char **env, const Char *varname ); +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 ); /* --------------------------------------------------------------------- Exports of vg_message.c @@ -1456,10 +1458,6 @@ extern void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child); extern void VG_(init_preopened_fds) ( void ); 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 ------------------------------------------------------------------ */ diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c index b5cf91dbea..1724aadb97 100644 --- a/coregrind/vg_mylibc.c +++ b/coregrind/vg_mylibc.c @@ -1488,6 +1488,102 @@ Int VG_(setpgid) ( Int pid, Int pgrp ) return VG_(do_syscall)(__NR_setpgid, pid, pgrp); } +/* 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) +{ + 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'; +} + + +// 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; + Char* ld_library_path_str = NULL; + Char* buf; + + // Find LD_* variables + 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); + + // Remove Valgrind-specific entries from LD_*. + VG_(sprintf)(buf, "%s*/vg_inject.so", VG_(libdir)); + mash_colon_env(ld_preload_str, buf); + VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir)); + mash_colon_env(ld_preload_str, buf); + VG_(sprintf)(buf, "%s*", VG_(libdir)); + 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 ) @@ -1506,36 +1602,8 @@ Int VG_(system) ( Char* cmd ) /* restore the DATA rlimit for the child */ VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data)); - if (envp == NULL) { - Int i; - Char* ld_preload_str = NULL; - Char* ld_library_path_str = NULL; - Char* buf; - - envp = env_clone(VG_(client_envp)); - - 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); - - VG_(arena_free)(VG_AR_CORE, buf); - } + envp = env_clone(VG_(client_envp)); + VG_(env_remove_valgrind_env_stuff)( envp ); argv[0] = "/bin/sh"; argv[1] = "-c"; diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c index eae5c86282..dbcf61acb8 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -153,67 +153,6 @@ static Bool valid_client_addr(Addr start, UInt size, ThreadId tid, const Char *s return ret; } -/* 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 ------------------------------------------------------------------ */ @@ -1839,39 +1778,14 @@ PRE(execve) VG_(nuke_all_threads_except)( VG_INVALID_THREADID ); { - /* 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 ); } }