Discussion:
Reconstructing mmaps from sysctl KERN_PROC_VMMAP
(too old to reply)
Paul Floyd
2024-02-12 07:21:23 UTC
Permalink
Hi

I'm having difficulty with one of the Valgrind developer mode options,
"--sanity-level=3". With this option every time that there is a change
to things that are memory mapped Valgrind will do a check that its
internal memory map model is consistent with what the OS reports. It
gets the OS mappings via sysctl KERN_PROC_VMMAP.

This breaks down for mappings done with MAP_STACK (which happens each
time a thread is created). For mmap calls like this there will initially
be two mappings, a 128k stack mapping and a 'length-128k' guard mapping.
This first guard page is really the stack growth area, and the size of
the stack growth chunks is controlled by sysctl KERN_SGROWSIZ. As the
stack grows more sgrowsiz mappings get created, eating up the stack
growth guard mapping.

Is there any way to work out that the split growth guard and sgrowsiz
stack mappings call come from a single mmap MAP_STACK? Indeed, is the
kernel capable of telling that these mappings came from the same mmap?

My only idea at the moment is to modify the checks so that if Valgrind
sees an anon RW mapping in its model that matches a zero prot guard plus
some number of sgrowsiz RW stack mappings that have the same size as the
singkle anon RW mapping then it is probably OK. And if the size is
THR_STACK_DEFAULT it's even more likely to be OK. Of course, users could
change the thread stacksize and I suppose that if you try hard enough
you can manually arrive at a mapping with multiple mmap calls that looks
like a single mmap MAP_STACK.


A+
Paul


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Konstantin Belousov
2024-02-12 07:54:36 UTC
Permalink
Post by Paul Floyd
Hi
I'm having difficulty with one of the Valgrind developer mode options,
"--sanity-level=3". With this option every time that there is a change to
things that are memory mapped Valgrind will do a check that its internal
memory map model is consistent with what the OS reports. It gets the OS
mappings via sysctl KERN_PROC_VMMAP.
This breaks down for mappings done with MAP_STACK (which happens each time a
thread is created). For mmap calls like this there will initially be two
mappings, a 128k stack mapping and a 'length-128k' guard mapping. This first
guard page is really the stack growth area, and the size of the stack growth
chunks is controlled by sysctl KERN_SGROWSIZ. As the stack grows more
sgrowsiz mappings get created, eating up the stack growth guard mapping.
Is there any way to work out that the split growth guard and sgrowsiz stack
mappings call come from a single mmap MAP_STACK? Indeed, is the kernel
capable of telling that these mappings came from the same mmap?
My only idea at the moment is to modify the checks so that if Valgrind sees
an anon RW mapping in its model that matches a zero prot guard plus some
number of sgrowsiz RW stack mappings that have the same size as the singkle
anon RW mapping then it is probably OK. And if the size is THR_STACK_DEFAULT
it's even more likely to be OK. Of course, users could change the thread
stacksize and I suppose that if you try hard enough you can manually arrive
at a mapping with multiple mmap calls that looks like a single mmap
MAP_STACK.
If you see a guard entry which is followed by a swap map entry with
KVME_FLAG_GROWS_DOWN flag, then this is definitely the stack pair.


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Paul Floyd
2024-02-13 20:45:40 UTC
Permalink
Post by Konstantin Belousov
If you see a guard entry which is followed by a swap map entry with
KVME_FLAG_GROWS_DOWN flag, then this is definitely the stack pair.
OK thanks. I'll rewrite those functions to look for that kind of pattern.

A+

Paul

Loading...