|
From: Joern R. <joe...@st...> - 2005-05-03 18:03:07
Attachments:
sbitmap.h
valgrind-tst2.c
|
I get false positives when running a gcc cross-compiler under valgrind 2.4.0 with the memcheck tool. It mallocs a simple bitmap, sets every bit in the bitmap, and later tests the bits. I have attached a stripped-down testcase. It appears that any 64-bit values that are fully initialized bit by bit are OK, as is testing any bit in the high part. However, the lowpart bits on the last (partially-initialized) 64 bit value generate a spurious error message from valgrind: ==7161== Conditional jump or move depends on uninitialised value(s) ==7161== at 0x804867B: check (valgrind-tst2.c:44) ==7161== by 0x8048736: main (valgrind-tst2.c:72) ==7161== ==7161== ERROR SUMMARY: 32 errors from 1 contexts (suppressed: 13 from 1) ==7161== malloc/free: in use at exit: 0 bytes in 0 blocks. ==7161== malloc/free: 1 allocs, 1 frees, 28 bytes allocated. ==7161== For counts of detected errors, rerun with: -v ==7161== No malloc'd blocks -- no leaks are possible. This lead me to believe that it is probably the shrd insruction that looses validity information: 0x080ca128 <verify_loop_structure+816>: shrd %cl,%edx,%eax $cl contains the lower 6 bit of the bit number, $edx the highpart, and $eax the lowpart of a 64 bit element. Only bit zero of the result is actually used - if any bit of this operation is used at all. The false positives are reproducible compiling the testcase with any of gcc 2.95.2 , 2.9.6 (redhat), 3.2.3 or 3.4.3 A further problem that I have observed is that there doesn't seem to be a way to attach gdb each time an error with identical backtrace is encountered. So when valgrind stops at the first iteration of a loop, you don't know if the problem is due to a special case in the first iteration, and the other instances are solely in other calls again at the first iteration, or if the problem appears in other iterations too. This is on Red Hat Enterprise Linux WS release 3 (Taroon Update 4) uname -a output: Linux linsvr1 2.4.21-20.ELsmp #1 SMP Wed Aug 18 20:31:57 EDT 2004 i686 athlon i386 GNU/Linux -bash-2.05b$ ls -l /lib/libc* -rwxr-xr-x 1 root root 1568524 Oct 22 2004 /lib/libc-2.3.2.so lrwxrwxrwx 1 root root 11 Sep 30 2004 /lib/libcap.so -> libcap.so.1 lrwxrwxrwx 1 root root 14 Sep 30 2004 /lib/libcap.so.1 -> libcap.so.1.10 -rwxr-xr-x 1 root root 10916 Jul 22 2004 /lib/libcap.so.1.10 lrwxrwxrwx 1 root root 17 Feb 6 03:38 /lib/libcom_err.so.2 -> libcom_err.so.2.0 -rwxr-xr-x 1 root root 5540 Oct 4 2004 /lib/libcom_err.so.2.0 -rwxr-xr-x 1 root root 23388 Oct 22 2004 /lib/libcrypt-2.3.2.so -rwxr-xr-x 1 root root 853564 Mar 8 2004 /lib/libcrypto.so.0.9.6b -rwxr-xr-x 1 root root 972156 Jun 22 2004 /lib/libcrypto.so.0.9.7a lrwxrwxrwx 1 root root 19 Feb 15 01:26 /lib/libcrypto.so.2 -> libcrypto.so.0.9.6b lrwxr-xr-x 1 root root 19 Sep 30 2004 /lib/libcrypto.so.4 -> libcrypto.so.0.9.7a lrwxrwxrwx 1 root root 17 Feb 6 03:38 /lib/libcrypt.so.1 -> libcrypt-2.3.2.so lrwxrwxrwx 1 root root 13 Feb 6 03:38 /lib/libc.so.6 -> libc-2.3.2.so |
|
From: Julian S. <js...@ac...> - 2005-05-03 18:40:53
|
Hi Joern Thanks for the bug report. > This lead me to believe that it is probably the shrd insruction that > looses validity information: Your analysis is right. Up to and including 2.4.0, memcheck approximated the behaviour of shrd/shld (but is exact for the normal shift insns). I can reproduce what you say using 2.4.0. Good news is that the 3.X line uses a new compilation pipeline which is significantly more accurate, not just for sh[lr]d but also for floating point and vector instructions. And so it runs your program without the false warning. 3.0 is still a work in progress, but is fairly solid on x86 and so you may want to use it instead. See http://www.valgrind.org/devel/cvs_svn.html for details on how to check it out of svn and build; it's easy. J (irrelevant details ...) 3.0's translation into IR of the offending insn is ... 0x80484C1: shrdl %cl, %esi, %ebx ------ IMark(0x80484C1, 3) ------ PUT(56) = 0x80484C1:I32 t25 = GET:I32(24) t26 = GET:I32(12) t27 = And8(GET:I8(4),0x1F:I8) t28 = 32HLto64(t25,t26) t29 = 64to32(Shr64(t28,t27)) t30 = 64to32(Shr64(t28,And8(Sub8(t27,0x1:I8),0x1F:I8))) PUT(32) = Mux0X(t27,GET:I32(32),0x1B:I32) PUT(36) = Mux0X(t27,GET:I32(36),t29) PUT(40) = Mux0X(t27,GET:I32(40),t30) PUT(44) = 0x0:I32 PUT(12) = t29 Because memcheck tracks exactly the behaviour of Shr64 and all the other primops, you get exact handling of shrdl "for free". |