Summary: | false positive : move depends on uninitialised value wcscpy | ||
---|---|---|---|
Product: | [Developer tools] valgrind | Reporter: | David Dyck <david.dyck> |
Component: | memcheck | Assignee: | Julian Seward <jseward> |
Status: | RESOLVED DUPLICATE | ||
Severity: | normal | CC: | david.dyck, philippe.waroquiers |
Priority: | NOR | ||
Version: | 3.7.0 | ||
Target Milestone: | --- | ||
Platform: | openSUSE | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: |
sample C program that demonstrates false positives
output from: g++ -m32 -Wall -O0 -g valgrind_bug_wcscpy.c && valgrind -v --track-origins=yes ./a.out |
removed the "64 bit" portion of the comment The false positive returns when compiling with g++ instead of gcc e.g. both g++ -m32 -Wall -O0 -g valgrind_bug_wcscpy.c && valgrind --track-origins=yes ./a.out and g++ -m64 -Wall -O0 -g valgrind_bug_wcscpy.c && valgrind --track-origins=yes ./a.out yield errors like: ==15026== Conditional jump or move depends on uninitialised value(s) ==15026== at 0x5789F05: __wcscpy_ssse3 (in /lib64/libc-2.15.so) ==15026== by 0x400687: main (valgrind_bug_wcscpy.c:31) ==15026== Uninitialised value was created by a stack allocation ==15026== at 0x40065C: main (valgrind_bug_wcscpy.c:23) gcc (SUSE Linux) 4.7.1 20120723 [gcc-4_7-branch revision 189773] > ldd a.out linux-vdso.so.1 (0x00007fff10bff000) libc.so.6 => /lib64/libc.so.6 (0x00007fd84dcda000) /lib64/ld-linux-x86-64.so.2 (0x00007fd84e07f000) g++ (SUSE Linux) 4.7.1 20120723 [gcc-4_7-branch revision 189773] > ldd a.out linux-vdso.so.1 (0x00007ffff9790000) libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fb62ab54000) libm.so.6 => /lib64/libm.so.6 (0x00007fb62a85d000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fb62a647000) libc.so.6 => /lib64/libc.so.6 (0x00007fb62a2a2000) /lib64/ld-linux-x86-64.so.2 (0x00007fb62ae5b000) Created attachment 83258 [details]
output from: g++ -m32 -Wall -O0 -g valgrind_bug_wcscpy.c && valgrind -v --track-origins=yes ./a.out
Interesting that the only difference between getting false positives or not is the
compiler
# no false positive
gcc -m32 -Wall -O0 -c valgrind_bug_wcscpy.c && g++ -m32 valgrind_bug_wcscpy.o && valgrind -v --track-origins=yes ./a.out
# false positives
g++ -m32 -Wall -O0 -c valgrind_bug_wcscpy.c && g++ -m32 valgrind_bug_wcscpy.o && valgrind -v --track-origins=yes ./a.out
Maybe this is a red-herring - and more optimizations are happening in one of the compilers.
> diff -u valgrind_bug_wcscpy.s*
--- valgrind_bug_wcscpy.s.g++ 2013-10-31 15:52:25.330401000 -0700
+++ valgrind_bug_wcscpy.s.gcc 2013-10-31 15:52:38.120528000 -0700
@@ -35,15 +35,15 @@
andl $-16, %esp
subl $96, %esp
movl $.LC0, 4(%esp)
- leal 16(%esp), %eax
+ leal 56(%esp), %eax
movl %eax, (%esp)
call wcscpy
- leal 16(%esp), %eax
- movl %eax, 4(%esp)
leal 56(%esp), %eax
+ movl %eax, 4(%esp)
+ leal 16(%esp), %eax
movl %eax, (%esp)
call wcscpy
- leal 56(%esp), %eax
+ leal 16(%esp), %eax
movl %eax, (%esp)
call wcslen
leave
Also occurs with valgrind 3.8.1 > valgrind --version valgrind-3.8.1 > g++ -Wall -O0 -g valgrind_bug_wcscpy.c && valgrind --track-origins=yes ./a.out ==9859== Memcheck, a memory error detector ==9859== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==9859== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==9859== Command: ./a.out ==9859== ==9859== Conditional jump or move depends on uninitialised value(s) ==9859== at 0x42DC491: __wcscpy_ssse3 (in /lib/libc-2.15.so) ==9859== by 0x41AF3D4: (below main) (in /lib/libc-2.15.so) ==9859== Uninitialised value was created by a stack allocation ==9859== at 0x8048522: main (valgrind_bug_wcscpy.c:23) ==9859== ==9859== Conditional jump or move depends on uninitialised value(s) ==9859== at 0x42DC9E7: __wcscpy_ssse3 (in /lib/libc-2.15.so) ==9859== by 0x41AF3D4: (below main) (in /lib/libc-2.15.so) ==9859== Uninitialised value was created by a stack allocation ==9859== at 0x8048522: main (valgrind_bug_wcscpy.c:23) ==9859== ==9859== Conditional jump or move depends on uninitialised value(s) ==9859== at 0x42DC9EB: __wcscpy_ssse3 (in /lib/libc-2.15.so) ==9859== by 0x41AF3D4: (below main) (in /lib/libc-2.15.so) ==9859== Uninitialised value was created by a stack allocation ==9859== at 0x8048522: main (valgrind_bug_wcscpy.c:23) ==9859== ==9859== ==9859== HEAP SUMMARY: ==9859== in use at exit: 0 bytes in 0 blocks ==9859== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==9859== ==9859== All heap blocks were freed -- no leaks are possible ==9859== ==9859== For counts of detected and suppressed errors, rerun with: -v ==9859== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) I will continue to investigate, but this test case does not seem to be reproducible with 3.9.0 > valgrind --version valgrind-3.9.0 > valgrind --track-origins=yes ./a.out ==30515== Memcheck, a memory error detector ==30515== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==30515== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info ==30515== Command: ./a.out ==30515== ==30515== ==30515== HEAP SUMMARY: ==30515== in use at exit: 0 bytes in 0 blocks ==30515== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==30515== ==30515== All heap blocks were freed -- no leaks are possible ==30515== ==30515== For counts of detected and suppressed errors, rerun with: -v ==30515== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) (In reply to comment #5) > I will continue to investigate, but this test case does not seem to be > reproducible with 3.9.0 Thanks for verifying with 3.9.0. I think this is a duplicate of 307828, which is fixed in 3.9.0 , so closing it. Please re-open if needed. *** This bug has been marked as a duplicate of bug 307828 *** |
Created attachment 83253 [details] sample C program that demonstrates false positives I've attached the sample program valgrind_bug_wcscpy.c that shows false positives that get in the way of finding real errors in our code. The bug does not show up if compiled as a 32 bit program on linux, or if I use memset() to pre-initialize the buffer. The bug does not show up if the same program uses the <string.h> functions strcpy and strlen which is my main argument as to why this is a false positive. --------------------- /* The following program causes valgrind to report an error ( false positive ) Compile: gcc -m64 -Wall -O0 -g valgrind_bug_wcscpy.c Execute: valgrind --track-origins=yes ./a.out Unexpected and undesirable results (false positive): ==15062== Conditional jump or move depends on uninitialised value(s) ==15062== at 0x4F75F05: __wcscpy_ssse3 (in /lib64/libc-2.15.so) ==15062== by 0x4005B7: main (valgrind_bug.c:31) ==15062== Uninitialised value was created by a stack allocation ==15062== at 0x40058C: main (valgrind_bug.c:23) */ // #include <stdio.h> #include <wchar.h> #include <string.h> int main() { wchar_t stackbuf1[10]; // if we init on allocation ( = { 0 }) no error // memset(stackbuf1, 0, sizeof(stackbuf1)); // if we pre-initialize the buffer, no error wcscpy(stackbuf1,L"hello"); // initialize (part of) stackbuf1 wchar_t stackbuf2[10]; wcscpy(stackbuf2, stackbuf1); // valgrind reports stackbuf1 unitialized return wcslen(stackbuf2); }