|
From: Yeshurun, M. <mei...@in...> - 2008-08-01 11:07:11
|
Hi,
I'd like to share with you the reason Valgrind could not reproduce the
memory violation we had. The faulty module was making decisions based on
block addresses, and the corruption only occurred when those addresses
satisfied certain conditions (it's actually a very well-written module
except for this bug).
I guess the simplest example of this would be the following program:
#include <stdlib.h>
#include <stdio.h>
int main()
{
void *p = malloc(8), *p2;
printf("%p\n", p);
scanf("%p", &p2);
if (p2 == p)
free((char*)p + 100);
}
If you enter the value printed, you get a glibc complaint. Now run
Valgrind, enter the same value as before, and Valgrind is silent. Same
binary, same input, but the problem is gone.
I believe this is the most common reason for cases where memory
corruptions are not reproduced when running Valgrind.
So is there any chance Valgrind could ever be enhanced to maintain
variable and heap block addresses so they match the addresses of a
native run?
Thanks!
Meir
-----Original Message-----
From: Julian Seward [mailto:js...@ac...]
Sent: Friday, July 18, 2008 11:06 AM
To: val...@li...
Cc: Yeshurun, Meir
Subject: Re: [Valgrind-users] "glibc detected..." error
On Friday 18 July 2008 00:01, Yeshurun, Meir wrote:
> I assume that Valgrind always knows, for each byte in the heap,
whether
> the process is allowed to access it
yes. In fact for each byte in the entire process it knows that.
> But Valgrind is supposed to always notify you of an invalid
read/write,
> regardless of the size of the free list and the red zones.
That's unfortunately not exactly correct (partially correct).
Consider the following two problems:
1. You allocate a block of size 1000 (say). By default the
16 byte area just beyond each end is marked as no-access.
That guarantees Memcheck can detect accesses in these areas.
But suppose it is an array of 20 50-byte items, and you have an
off-by-one error in the indexing. Then you get an access which
is 50 bytes outside the block. Will Memcheck detect that? Maybe,
maybe not. If this incorrect address happens to be inside a
neighbouring block, then no error will be reported.
In this example, increasing the red zone size to be 50 bytes or
more will guarantee that Memcheck detects the error.
2. You allocate a block of size N and then free it. A very long time
later you (incorrectly) access the block. Will Memcheck detect that?
Again, depends. Memcheck marks freed memory as no-access, to detect
this kind of error. But the problem is that if freed memory remains
no-access for ever, then the process will run out of memory in a
simple
loop like this
while (1) { char* x = malloc(10); free(x); }
So eventually Memcheck makes memory from freed blocks available for
allocation again. When it does that, it can no longer detect invalid
accesses to these freed blocks.
This is what the --freelist-vol parameter is for. Higher settings
cause Memcheck to hold on to freed memory for longer, which increases
the probability of detecting reads/writes to freed memory, but it
also
increases the total memory consumption of the process.
J
---------------------------------------------------------------------
Intel Israel (74) Limited
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
|