12-20-07 12:35 PM
chsalvia wrote:
> Valgrind will report errors if a program attempts to access
> uninitialized memory. Normally this is desirable debugging behavior.
Yes.
> But, Valgrind does not seem to consider reading from disk a form of
> initialization. So if you allocate a block of memory, and then
> immediately use it to read from disk with a low-level system call,
> such as read or pread, and then later access that memory block, or
> write it out to disk with write/pwrite, Valgrind thinks you are
> writing out an uninitialized block of memory.
This is incorrect.
$ cat foo.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int fd, count, res; char buf[4000];
if ((fd = open("/dev/zero", O_RDONLY)) < 0) return 1;
if (argc < 2) count = 4000; else count = 50;
res = read(fd, buf, count);
printf("READ: %d\n", res);
return buf[100];
}
$ gcc -O3 -Wall -ansi -pedantic foo.c
$ valgrind a.out
==26640== Memcheck, a memory error detector.
[...]
==26640==
--26640-- DWARF2 CFI reader: unhandled CFI instruction 0:50
--26640-- DWARF2 CFI reader: unhandled CFI instruction 0:50
READ: 4000
==26640==
==26640== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1)
==26640== malloc/free: in use at exit: 0 bytes in 0 blocks.
==26640== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
==26640== For counts of detected errors, rerun with: -v
==26640== All heap blocks were freed -- no leaks are possible.
$ valgrind a.out xx
==26641== Memcheck, a memory error detector.
[...]
==26641==
--26641-- DWARF2 CFI reader: unhandled CFI instruction 0:50
--26641-- DWARF2 CFI reader: unhandled CFI instruction 0:50
READ: 50
==26641== Syscall param exit_group(exit_code) contains uninitialised byte(s)
==26641== at 0x40C52AF: _Exit (in /lib/tls/libc-2.3.6.so)
==26641== by 0x404DE1D: (below main) (in /lib/tls/libc-2.3.6.so)
==26641==
==26641== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1)
==26641== malloc/free: in use at exit: 0 bytes in 0 blocks.
==26641== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
==26641== For counts of detected errors, rerun with: -v
==26641== All heap blocks were freed -- no leaks are possible.
In the first case, buf[100] was properly initialized by the read call,
but in the second case, it was not.
> Obviously, this can be easily fixed with a call to memset before
> reading from disk. But that's unnecessary and inefficient. Ideally,
> I'd like to do a #ifdef which would initialize the memory block only
> when the program is being run under Valgrind, in order to silence the
> error.
#ifdef is a compile-time mechanism. You'd need to make run-time checks
to decide whether your program is being run by valgrind or by a shell.
Regards.
[ Post a follow-up to this message ]
|