|
From: Nick L. <ni...@io...> - 2005-10-17 19:32:31
|
Hi
> Seriously now, my experience with Valgrind has been to the contrary.
> Sure, its tempting to dismiss error messages as false alarms. But so
> far, Valgrind was right about every error that I took the time to
> investigate carefully. You can't blame Valgrind for reporting cases of
> deliberate use of un-initialized values (and I've seen some of those).
Quite agree on the last point, which is why we weren't. As another poster
said, it's actually quite common in comms related code for there to be
valid UMR's.
Based on past good experiences I was surprised just how way off valgrind
was, hence the query really, and the reports of a function return value
being unintialised when it wasn't was particularly frustrating. I haven't
determined the syntax to suppress specific lines yet (can this even be
done?), so had to suppress the entire function which could have masked
genuine problems. As I said, valgrind has certainly been right on some C
projects in the past, so I didn't know what was up in this case. Purify
was spot on though.
I don't like to compare great free opensource efforts against highly
expensive commercial ones, but as well as an overhaul of the suppressions
mechanism, two features that really would be nice, and apologies if these
exist already, would be identifying variable names from addresses wherever
possible, and showing where freed memory was allocated from. In the
following case:
int main()
{
char* buf = malloc(5);
int i,j = 0;
buf[7] = 0;
free(buf);
buf[3] = 12;
return i + j;
}
Valgrind correctly reports the problems, although incorrectly says that
buf[7] is a write 2 bytes beyond the end of the memory when it's 3 bytes
beyond. The uninitialised value in the return is caught, however which
variable is at fault is not identified. Where the freed memory was
allocated from is also not shown.
In contrast, purify identifies correctly the write 3 bytes beyond the end
of the block, shows where the freed memory was allocated from, and most
crucially indicates that the problem in the return is with variable i. Of
course it's clear in this case, but in general, the symbolic
identification can be very useful in locating problems in compound
expressions.
VG
==9484== Invalid write of size 1
==9484== at 0x8048389: main (x.c:8)
==9484== Address 0x1BA5A02F is 2 bytes after a block of size 5 alloc'd
==9484== at 0x1B8FEA35: malloc (vg_replace_malloc.c:149)
==9484== by 0x8048375: main (x.c:5)
==9484==
==9484== Invalid write of size 1
==9484== at 0x80483A0: main (x.c:12)
==9484== Address 0x1BA5A02B is 3 bytes inside a block of size 5 free'd
==9484== at 0x1B8FF548: free (vg_replace_malloc.c:235)
==9484== by 0x8048396: main (x.c:10)
==9484==
==9484== Syscall param exit_group(exit_code) contains uninitialised byte(s)
==9484== at 0x1B9CC3F7: _Exit (in /lib/libc-2.3.2.so)
==9484== by 0x1B93391E: __libc_start_main (in /lib/libc-2.3.2.so)
==9484== by 0x80482CC: ??? (start.S:81)
Purify
**** Purify instrumented ./x (pid 9594) ****
ABW: Array bounds write:
* This is occurring while in:
main [x.c:8]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Writing 1 byte to 0x80b4927 in the heap.
* Address 0x80b4927 is 3 bytes past end of a malloc'd block at 0x80b4920
of 5 bytes.
* This block was allocated from:
malloc [rtlib.o]
main [x.c:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./x (pid 9594) ****
FMW: Free memory write:
* This is occurring while in:
main [x.c:12]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Writing 1 byte to 0x80b4923 in the heap.
* Address 0x80b4923 is 3 bytes into a freed block at 0x80b4920 of 5 bytes.
* This block was allocated from:
malloc [rtlib.o]
main [x.c:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
* There have been 0 frees since this block was freed from:
free [rtlib.o]
main [x.c:10]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./x (pid 9594) ****
UMR: Uninitialized memory read:
* This is occurring while in:
main [x.c:14]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Reading 4 bytes from 0xbfffeea0 on the stack.
* Address 0xbfffeea0 is local variable "i" in function main.
Nick
|