|
From: Konstantin S. <kon...@gm...> - 2009-05-22 09:38:42
|
Hi Nick, Here is my attempt for a patch and a unittest. The first thing you would probably ask is how does this affect the performance of Memcheck. Would you suggest a benchmark to try? Other comments? Thanks, --kcc % g++ -g -DHAVE_IGNORE_ANNOTATIONS memcheck_annotations.cc -I $HOME/valgrind/ann/inst/include && $HOME/valgrind/ann/inst/bin/valgrind -q ./a.out % g++ -g memcheck_annotations.cc -I $HOME/valgrind/ann/inst/include && $HOME/valgrind/ann/inst/bin/valgrind -q ./a.out 2>&1 | head ==16258== Invalid write of size 1 ==16258== at 0x4006D9: int test_memcheck_annotations<signed char>() (memcheck_annotations.cc:16) ==16258== by 0x4006A4: main (memcheck_annotations.cc:31) ==16258== Address 0x58f603a is 0 bytes after a block of size 10 alloc'd ==16258== at 0x4C1C87C: operator new[](unsigned long) (vg_replace_malloc.c:245) ==16258== by 0x4006CC: int test_memcheck_annotations<signed char>() (memcheck_annotations.cc:13) ==16258== by 0x4006A4: main (memcheck_annotations.cc:31) ==16258== ==16258== Invalid read of size 1 ==16258== at 0x4006E4: int test_memcheck_annotations<signed char>() (memcheck_annotations.cc:19) % On Wed, Apr 8, 2009 at 6:25 PM, Konstantin Serebryany <kon...@gm...> wrote: > On Wed, Apr 8, 2009 at 2:07 PM, Nicholas Nethercote > <n.n...@gm...> wrote: >> On Wed, Apr 8, 2009 at 2:20 AM, Konstantin Serebryany >> <kon...@gm...> wrote: >>> >>> Memcheck has client requests such as VALGRIND_MAKE_MEM_DEFINED(mem, size). >>> These requests mark memory as initialized (i.e. safe to read). >>> But there is no annotation that marks a specific memory access as safe. >>> Is that not included intentionally? If yes, what was the reason? >>> If no, do you mind to include such request(s)? >> >> I think the reason is that nobody has required them until now. >> >> I've previously thought about them in one context, involving more >> aggressive checking by Memcheck of a program. Imagine you have a data >> structure that should only be accessed through a small number of >> access functions. You could mark the data structure as unaddressable, >> and then wrap the accesses within the access functions with such >> annotations. That way you would immediately know if any other part of >> your program accessed the data structure not via those access >> functions, which could be due to (a) failure to observe the access >> function discipline, or (b) corrupted pointers or similar. >> >> I thought about doing this by marking the memory as >> addressable-and-defined, doing the read/write, then marking it >> unaddressable again, but your approach is more efficient. So I can see >> these annotations would be useful. Here's an attempt at what they >> would look like: >> >> // Memcheck normally checks that you do not read unaddressable or >> // addressable-but-undefined memory. This wrapper causes that >> // check to be omitted. >> VALGRIND_UNCHECKED_MEM_READ(mem) >> >> // Memcheck normally checks that you do not write unaddressable memory. >> // This wrapper causes that check to be omitted. >> VALGRIND_UNCHECKED_MEM_WRITE(mem) > > In addition to these, we may want to have a BEGIN/END form, for the > cases when the access happens in a routine which we can not annotate > or which may be used in other contexts. > VALGRIND_IGNORE_READS_BEGIN() > external_function(pointer_to_uninitialized_but_safe_to_use_memory) > VALGRIND_IGNORE_READS_END() > > >> >> >>> Example: >>> >>> int *p = (int*)malloc(100); >>> // p is 4-aligned and not initialized >> >> Not quite. p is 4-aligned and initialized. *p is unitialized. > ah, yes. > > --kcc > |