|
From: John v. S. <jc...@cs...> - 2007-05-24 13:26:27
|
Hi, After reading the latest paper from Nick and Julian about Valgrind [1] I was wondering at which address the valgrind tool (incl. core) are loaded. Reading the paper, it states that the loader is loaded at 0x38000000 (896 mega bytes) on x86/linux because that address is usually free (is this a special boundary? Just like the 3G/1G split in the previous loader?). Then the tool+core are loaded with execve, but are they loaded at 0x38000000 also (and thus overwrite the loader) or are they loaded much higher? If they are loaded at 0x38000000, that means that the program being executed under control of Valgrind should not touch the memory above 0x38000000 right? Which seems a bit low to me. If the tool+core are loaded higher, then the question remains at which address? Thanks in advance and sorry for the question which may be a bit trivial. Cheers, John 1. Valgrind: A Framework for Heavyweight Dynamic Binary Instrumentation. Nicholas Nethercote and Julian Seward. Proceedings of PLDI 2007, San Diego, California, USA, June 2007. http://www.valgrind.org/docs/pubs.html |
|
From: Tom H. <to...@co...> - 2007-05-24 13:30:58
|
In message <465...@cs...>
John van Schie <jc...@cs...> wrote:
> After reading the latest paper from Nick and Julian about Valgrind [1] I
> was wondering at which address the valgrind tool (incl. core) are loaded.
>
> Reading the paper, it states that the loader is loaded at 0x38000000
> (896 mega bytes) on x86/linux because that address is usually free (is
> this a special boundary? Just like the 3G/1G split in the previous
> loader?). Then the tool+core are loaded with execve, but are they loaded
> at 0x38000000 also (and thus overwrite the loader) or are they loaded
> much higher?
Only the loaders position is really important, because after that
valgrind is in control and can keep track of where everything is and
allocate memory to different things as necessary.
> If they are loaded at 0x38000000, that means that the program being
> executed under control of Valgrind should not touch the memory above
> 0x38000000 right? Which seems a bit low to me.
The program being executed under valgrind's control should not assume
it can touch any particular memory, which is what all programs should
be doing anyway.
What it should do is ask for memory with malloc or mmap, and valgrind
will ensure it is given memory that is safe to use. If it really must
use a fixed address it should use mmap to ask for access to it and
valgrind will either accept or reject that request just as the OS would
normally do.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: John v. S. <jc...@cs...> - 2007-05-24 14:06:55
|
Tom Hughes wrote: > Only the loaders position is really important, because after that > valgrind is in control and can keep track of where everything is and > allocate memory to different things as necessary. Thanks for the quick answer Tom, much appreciated! This is clear to me, but still two questions ;) 1) Why 0x38000000? It just seems such a weird number to me. 2) With the risk of asking something really stupid: Nick mentions in his PHD thesis, the translated client code runs within a x86 segment to prevent it from writing to the Valgrind address space. But isn't this impossible if the Valgrind address space is in the middle of the applications address space? Or is my knowledge of x86 severely lacking in this case? Cheers, John |
|
From: Tom H. <to...@co...> - 2007-05-24 14:47:49
|
In message <465...@cs...>
John van Schie <jc...@cs...> wrote:
> Tom Hughes wrote:
>
>> Only the loaders position is really important, because after that
>> valgrind is in control and can keep track of where everything is and
>> allocate memory to different things as necessary.
>
> Thanks for the quick answer Tom, much appreciated! This is clear to me,
> but still two questions ;)
>
> 1) Why 0x38000000? It just seems such a weird number to me.
It is below 1Gb so even a kernel with 1:3 user:kernel address space
split won't break it.
The precise address is somewhat arbitrary and is just designed to keep
the loader out of the way of the normal default load address of a
program (though that isn't normally critical) whilst ensuring the
loader can be loaded below 1Gb.
> 2) With the risk of asking something really stupid: Nick mentions in his
> PHD thesis, the translated client code runs within a x86 segment to
> prevent it from writing to the Valgrind address space. But isn't this
> impossible if the Valgrind address space is in the middle of the
> applications address space? Or is my knowledge of x86 severely lacking
> in this case?
That was an old system, and is no longer the case in the current code.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: Julian S. <js...@ac...> - 2007-05-24 14:29:11
|
> Thanks for the quick answer Tom, much appreciated! This is clear to me, > but still two questions ;) > > 1) Why 0x38000000? It just seems such a weird number to me. It seems arbitrary but in fact it is a good compromise given the constraints. In most cases Linux allows processes to access the lowest 3GB of memory, but sometimes this is limited to 2 or even 1 GB. So 0x38000000 is (7/8) * 1 GB, so V will work even on a system with only 1GB for user space. However, 0x38000000 is almost always far away from the default load address of executables (which is usually much lower) and so it pretty much guarantees that V will not conflict with the client executable's load address. > 2) With the risk of asking something really stupid: Nick mentions in his > PHD thesis, the translated client code runs within a x86 segment to > prevent it from writing to the Valgrind address space. But isn't this > impossible if the Valgrind address space is in the middle of the > applications address space? Not any more; this was removed because it is inflexible and causes various kinds of address-space layout problems. Also it's unportable; it does not work on PowerPC, and amd64 segmentation is a bit different too. So now there is no segmentation usage. As Tom says, V just tries to ensure the client does not conflict with itself, but otherwise the memory layout is quite flexible, and in the memory constrained case Valgrind's and the clients memory can be arbitrarily interleaved. However, in general Valgrind's address space manager tries to keep Valgrind's own memory far away from that of the client, so as to minimise the chances that it gets corrupted by errors in the client. Because, most of the time, the amount of address space actually used is much less than what is available, this heuristic usually works pretty well. J |
|
From: Nicholas N. <nj...@cs...> - 2007-05-24 22:25:00
|
On Thu, 24 May 2007, Julian Seward wrote: >> 1) Why 0x38000000? It just seems such a weird number to me. > > It seems arbitrary but in fact it is a good compromise given the > constraints. In most cases Linux allows processes to access the > lowest 3GB of memory, but sometimes this is limited to 2 or even > 1 GB. So 0x38000000 is (7/8) * 1 GB, so V will work even on a > system with only 1GB for user space. However, 0x38000000 is > almost always far away from the default load address of executables > (which is usually much lower) and so it pretty much guarantees that > V will not conflict with the client executable's load address. If you run "cat /proc/self/maps" you'll see how the address space normally is laid out, and "valgrind cat /proc/self/maps" how Valgrind changes this. Only the tool+core binary gets loaded at 0x38000000, and it's something like 2.5MB, ie. small. All the other memory dynamically allocated by the tool and core can go anywhere. Nick |