|
From: Nicholas N. <nj...@ca...> - 2004-01-26 17:10:43
|
CVS commit by nethercote:
Patch from Tom Hughes:
Patch to provide a proper environment to the debugger
Although this patch isn't strictly needed to allow alternative debuggers to
be used, it is needed if you want to use an X based debugger such as ups
(and presumably ddd) as VG_(system) has until now passed an empty
enviroment when starting the debugger but that causes DISPLAY to be lost.
This patch causes VG_(system) to pass a copy of the client environment
instead, with the necessary mashing done to clean up the LD_xxx variables.
M +5 -0 vg_include.h 1.177
M +62 -2 vg_mylibc.c 1.68
M +8 -8 vg_syscalls.c 1.82
--- valgrind/coregrind/vg_include.h #1.176:1.177
@@ -1088,4 +1088,5 @@ extern Int VG_(connect_via_socket)( UCha
/* Environment manipulations */
+extern Char **VG_(env_clone) ( Char **oldenv );
extern Char* VG_(env_getenv) ( Char **env, Char* varname );
extern Char **VG_(env_setenv) ( Char ***envp, const Char* varname, const Char *val );
@@ -1414,4 +1415,8 @@ extern Bool VG_(sysinfo_page_exists);
extern Addr VG_(sysinfo_page_addr);
+/* Walk through a colon separated list variable, removing entries
+ which match pattern. */
+extern void VG_(mash_colon_env)(Char *varp, const Char *pattern);
+
/* Something of a function looking for a home ... start up debugger. */
extern void VG_(start_debugger) ( Int tid );
--- valgrind/coregrind/vg_mylibc.c #1.67:1.68
@@ -1344,4 +1344,30 @@ Bool VG_(getcwd_alloc) ( Char** out )
------------------------------------------------------------------ */
+/* clone the environment */
+Char **VG_(env_clone) ( Char **oldenv )
+{
+ Char **oldenvp;
+ Char **newenvp;
+ Char **newenv;
+ Int envlen;
+
+ for (oldenvp = oldenv; oldenvp && *oldenvp; oldenvp++);
+
+ envlen = oldenvp - oldenv + 1;
+
+ newenv = VG_(arena_malloc)(VG_AR_CORE, envlen * sizeof(Char **));
+
+ oldenvp = oldenv;
+ newenvp = newenv;
+
+ while (oldenvp && *oldenvp) {
+ *newenvp++ = *oldenvp++;
+ }
+
+ *newenvp = *oldenvp;
+
+ return newenv;
+}
+
void VG_(env_unsetenv) ( Char **env, const Char *varname )
{
@@ -1497,5 +1523,4 @@ Int VG_(system) ( Char* cmd )
{
Int pid, res;
- void* environ[1] = { NULL };
if (cmd == NULL)
return 1;
@@ -1505,5 +1530,38 @@ Int VG_(system) ( Char* cmd )
if (pid == 0) {
/* child */
+ static Char** envp = NULL;
Char* argv[4];
+
+ if (envp == NULL) {
+ Int i;
+ Char* ld_preload_str = NULL;
+ Char* ld_library_path_str = NULL;
+ Char* buf;
+
+ envp = VG_(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);
+ }
+
argv[0] = "/bin/sh";
argv[1] = "-c";
@@ -1510,6 +1568,8 @@ Int VG_(system) ( Char* cmd )
argv[2] = cmd;
argv[3] = 0;
+
(void)VG_(do_syscall)(__NR_execve,
- (UInt)"/bin/sh", (UInt)argv, (UInt)&environ);
+ (UInt)"/bin/sh", (UInt)argv, (UInt)envp);
+
/* If we're still alive here, execve failed. */
return -1;
--- valgrind/coregrind/vg_syscalls.c #1.81:1.82
@@ -164,5 +164,5 @@ static Bool valid_client_addr(Addr start
delimited by ':' are considered to be '.' in a path.
*/
-static void mash_colon_env(Char *varp, const Char *remove_pattern)
+void VG_(mash_colon_env)(Char *varp, const Char *remove_pattern)
{
Char *const start = varp;
@@ -1870,11 +1870,11 @@ PRE(execve)
VG_(sprintf)(buf, "%s*/vg_inject.so", VG_(libdir));
- mash_colon_env(ld_preload_str, buf);
+ VG_(mash_colon_env)(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
- mash_colon_env(ld_preload_str, buf);
+ VG_(mash_colon_env)(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*", VG_(libdir));
- mash_colon_env(ld_library_path_str, buf);
+ VG_(mash_colon_env)(ld_library_path_str, buf);
VG_(env_unsetenv)(envp, VALGRINDCLO);
|