|
From: Nicholas N. <nj...@ca...> - 2003-09-05 22:17:00
|
On Fri, 15 Aug 2003, Santeri Paavolainen wrote: > >Wouldn't it be possible for valgrind to realise that the required > >environment variables aren't present and add them in again, either by > >mallocing some space for the new env array and the env entries, or by > >using a few static buffers ? > > 1. valgrind.so is hooked using LD_PRELOAD > 2. Command line arguments are passed to coregrind through the VG_ARGS > environmental variable. > 3. When an execve is trapped (vg_syscalls.c), clo_trace_children is > checked: if child tracing is enabled, valgrind does nothing. If child > tracing is disabled, mash_LD_PRELOAD_and_LD_LIBRARY_PATH is called to > modify LD_PRELOAD and LD_LIBRARY_PATH to remove valgrind. > > To allow tracing environmetal variables, I think valgrind should instead > always remove itself from LD_PRELOAD, LD_LIBRARY_PATH and clear VG_ARGS > from the environment. When it traps the execve system call, it would > look into clo_trace_children, and if child tracing is enabled, > LD_PRELOAD, LD_LIBRARY_PATH and VG_ARGS would be modified to include the > original values (since valgrind knows what the values are, this step > would just copy the known correct values in). I've been thinking about this. It is difficult. Currently, when an execve happens, if Valgrind doesn't want to trace into the child then it removes the relevant substrings from the LD_PRELOAD and LD_LIBRARY_PATH variables that are present in the 'envp' arg to execve(). (It falls over if they are missing from 'envp'.) With your proposal, Valgrind would remove the substrings at startup (and also clear VG_ARGS). When an execve happens, if Valgrind does want to trace into the children, it would add the substrings back to LD_PRELOAD and LD_LIBRARY_PATH, and restore VG_ARGS. Here's the difficulty: 'envp' is a NULL-terminated char* array. If any of the three variables weren't present, Valgrind would have to make a new copy of 'envp', copying all the old information and adding the missing variable(s). (Unless we knew there was enough room to add the new entries require, but I can't see how we could possibly know that.) The first, smaller problem: this is a space leak -- if execve happened lots of times, this would add up. The second, bigger problem: this is a space leak -- if 'envp' was malloc'd by the client program, Valgrind will (if running Memcheck or Addrcheck as its skin) identify this as a lost heap block. Which is bad, because it's not the client's fault. Valgrind can't try to free it, because 'envp' might not be malloc'd. I can't see how using static buffers would get around these problems, either. This is a shame, because Valgrind's current handling of all this is definitely broken. Can anyone see a way out? N |