Summary: | Valgrind invalid read in unaligned memcpy with Intel compiler v9 | ||
---|---|---|---|
Product: | [Developer tools] valgrind | Reporter: | James Farmer <james.farmer> |
Component: | memcheck | Assignee: | Julian Seward <jseward> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | nunoplopes |
Priority: | NOR | ||
Version: | 3.2.1 | ||
Target Milestone: | --- | ||
Platform: | unspecified | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: |
Test case
Test case 2 - demonstrates unexpected "uninitialised value" error Valgrind output from test case 2 |
Description
James Farmer
2007-01-08 15:58:51 UTC
Created attachment 19195 [details]
Test case
What happens if you run with --alignment=16 ? Thanks. That removes the errors that were displayed by our test case but still leaves lots of other valgrind errors in our main program (which we assume are related, since they all vanish if we disable the memcpy intrinsic). I'll try to create another test case to illustrate these. For example, setting len=5886 in our above test case results in: ================================================================ ==20671== Memcheck, a memory error detector. ==20671== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==20671== Using LibVEX rev 1658, a library for dynamic binary translation. ==20671== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==20671== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==20671== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==20671== --20671-- Command line --20671-- a.out --20671-- Startup, with flags: --20671-- -v --20671-- --alignment=16 --20671-- Contents of /proc/version: --20671-- Linux version 2.4.20-8smp (bhcompile@porky.devel.redhat.com) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #1 SMP Thu Mar 13 17:45:54 EST 2003 --20671-- Arch and hwcaps: X86, x86-sse1-sse2 --20671-- Valgrind library directory: /usr/local/lib/valgrind --20671-- Reading syms from /lib/ld-2.3.2.so (0x4000000) --20671-- Reading syms from /home/port/test/a.out (0x8048000) --20671-- Reading syms from /usr/local/lib/valgrind/x86-linux/memcheck (0x38000000) --20671-- object doesn't have a dynamic symbol table --20671-- Reading suppressions file: /usr/local/lib/valgrind/default.supp --20671-- REDIR: 0x40114A0 (index) redirected to 0x38020EEB (vgPlain_x86_linux_REDIR_FOR_index) --20671-- Reading syms from /usr/local/lib/valgrind/x86-linux/vgpreload_core.so (0x4017000) --20671-- Reading syms from /usr/local/lib/valgrind/x86-linux/vgpreload_memcheck.so (0x4019000) ==20671== WARNING: new redirection conflicts with existing -- ignoring it --20671-- new: 0x040114A0 (index ) R-> 0x0401C180 index --20671-- REDIR: 0x4011640 (strlen) redirected to 0x401C3D4 (strlen) --20671-- Reading syms from /lib/libm-2.3.2.so (0x4032000) --20671-- Reading syms from /lib/libgcc_s-3.2.2-20030225.so.1 (0x4054000) --20671-- object doesn't have a symbol table --20671-- Reading syms from /lib/libc-2.3.2.so (0x405C000) --20671-- Reading syms from /lib/libdl-2.3.2.so (0x4196000) --20671-- REDIR: 0x40D6500 (rindex) redirected to 0x401C0A8 (rindex) --20671-- REDIR: 0x40D7B20 (memset) redirected to 0x401CCB4 (memset) len=5886, readoff=1 --20671-- REDIR: 0x40CED80 (malloc) redirected to 0x401A64C (malloc) ==20671== Invalid read of size 8 ==20671== at 0x8048FE8: (within /home/port/test/a.out) ==20671== Address 0x419A758 is 5,880 bytes inside a block of size 5,886 alloc'd ==20671== at 0x401A6CE: malloc (vg_replace_malloc.c:149) ==20671== by 0x8048652: main (in /home/port/test/a.out) --20671-- REDIR: 0x40CEF40 (free) redirected to 0x401B203 (free) len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 len=5886, readoff=1 ==20671== ==20671== ERROR SUMMARY: 16 errors from 1 contexts (suppressed: 19 from 1) ==20671== ==20671== 16 errors in context 1 of 1: ==20671== Invalid read of size 8 ==20671== at 0x8048FE8: (within /home/port/test/a.out) ==20671== Address 0x419A758 is 5,880 bytes inside a block of size 5,886 alloc'd ==20671== at 0x401A6CE: malloc (vg_replace_malloc.c:149) ==20671== by 0x8048652: main (in /home/port/test/a.out) --20671-- --20671-- supp: 19 Ubuntu-stripped-ld.so ==20671== ==20671== IN SUMMARY: 16 errors from 1 contexts (suppressed: 19 from 1) ==20671== ==20671== malloc/free: in use at exit: 0 bytes in 0 blocks. ==20671== malloc/free: 32 allocs, 32 frees, 188,352 bytes allocated. ==20671== ==20671== All heap blocks were freed -- no leaks are possible. --20671-- memcheck: sanity checks: 14 cheap, 1 expensive --20671-- memcheck: auxmaps: 0 auxmap entries (0k, 0M) in use --20671-- memcheck: auxmaps: 0 searches, 0 comparisons --20671-- memcheck: SMs: n_issued = 10 (160k, 0M) --20671-- memcheck: SMs: n_deissued = 0 (0k, 0M) --20671-- memcheck: SMs: max_noaccess = 65535 (1048560k, 1023M) --20671-- memcheck: SMs: max_undefined = 0 (0k, 0M) --20671-- memcheck: SMs: max_defined = 22 (352k, 0M) --20671-- memcheck: SMs: max_non_DSM = 10 (160k, 0M) --20671-- memcheck: max sec V bit nodes: 0 (0k, 0M) --20671-- memcheck: set_sec_vbits8 calls: 0 (new: 0, updates: 0) --20671-- memcheck: max shadow mem size: 464k, 0M --20671-- translate: fast SP updates identified: 1,674 ( 87.1%) --20671-- translate: generic_known SP updates identified: 110 ( 5.7%) --20671-- translate: generic_unknown SP updates identified: 137 ( 7.1%) --20671-- tt/tc: 3,840 tt lookups requiring 3,902 probes --20671-- tt/tc: 3,840 fast-cache updates, 3 flushes --20671-- transtab: new 1,812 (37,841 -> 634,583; ratio 167:10) [0 scs] --20671-- transtab: dumped 0 (0 -> ??) --20671-- transtab: discarded 8 (193 -> ??) --20671-- scheduler: 1,458,352 jumps (bb entries). --20671-- scheduler: 14/2,232 major/minor sched events. --20671-- sanity: 15 cheap, 1 expensive checks. --20671-- exectx: 30,011 lists, 13 contexts (avg 0 per list) --20671-- exectx: 99 searches, 86 full compares (868 per 1000) --20671-- exectx: 0 cmp2, 66 cmp4, 0 cmpAll ================================================================ What we haven't managed to reproduce in a test case yet is our main program also reports lots of "Conditional jump or move depends on uninitialised value(s)" and "Use of uninitialised value" errors which seem to be related, as again they vanish if we disable the 'memcpy' intrinsic. I'm not saying the --alignment=16 flag is a recommended fix: V's malloc replacement should behave the same as libc one in this respect, and any difference is a bug. If you compile (with icc -O2) and run the following program (natively), the output should help you figure out the alignment that your native malloc produces. I always get the lowest digit as 0 or 8 indicating 8-aligned memory. #include <stdio.h> #include <stdlib.h> int main ( void ) { int i; char* p; for (i = 0; i < 20; i++) { p = malloc(i); printf("0x%02lx\n", ((unsigned long)p) & 0xFF); } return 0; } I see something similar (It looks 8-aligned to me: 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, 0xb8, 0xc8, 0xd8, 0xe8, 0xf8, 0x10, 0x28, 0x40, 0x58, 0x70, 0x88). But I'm not sure I follow the relevence, as memcpy doesn't have to start at an aligned address? Okay, I think the attached "Test Case 2" demonstrates the unexpected "Conditional jump or move depends on uninitialized value(s)" error. Basically, this generates a great big array which is only populated in two continuous blocks at the start and the end. The data is memcpy-ed into another array of the same size and the populated areas compared. After many tries with various random array sizes, I finally got it to produce the error: ==21603== Conditional jump or move depends on uninitialised value(s) ==21603== at 0x8048938: check_memory_area. (memcpytest2.c:61) ==21603== by 0x26412E: ??? The full valgrind -v output is rather long so I'll attach that as a file to this issue too. Again, the issue vanishes if the code is compiled -O1 rather than -O2. Created attachment 19198 [details]
Test case 2 - demonstrates unexpected "uninitialised value" error
Created attachment 19199 [details]
Valgrind output from test case 2
This is extremely strange. I have reproduced the problem and made a simplified test case. I don't think it is a bug in the Intel code. Valgrind appears to follow the same path of instructions through the fast memcpy intrinsic as native execution does. So I still have no idea why it complains. Try this. It's not a good solution but it's realistically about as good as can easily be done. It makes both your test cases run clean. Index: memcheck/mc_replace_strmem.c =================================================================== --- memcheck/mc_replace_strmem.c (revision 6492) +++ memcheck/mc_replace_strmem.c (working copy) @@ -401,6 +401,7 @@ MEMCPY(m_libc_soname, memcpy) MEMCPY(m_ld_so_1, memcpy) /* ld.so.1 */ +MEMCPY(NONE, _intel_fast_memcpy) #define MEMCMP(soname, fnname) \ A couple of people have confirmed this patch partially but not fully solves the problem. I'll put it into 3.2.2. Various fixes in 3.2.2 and trunk appear to have fixed, or mostly fixed this. Closing. Still getting this sometimes in 3.2.3. for us, it's an aligned source of 158 bytes. intel_fast_memcpy reads in 32 byte blocks, thus reading past the end. Since the compiler inserts the code locally, it doesn't need a PLT entry, and calls it drectly. Is there any way to make valgrind smart enough to recognize this situation? ==3749== Invalid read of size 8 ==3749== at 0x48CB638: (within /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x42C1B74: nsdo (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x43D8547: nsbasic_sd (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x43D877A: nssend (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x432B56E: nsnasend (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x438F43E: nacomsn (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x4386355: na_client (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x437CFD1: naconnect (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x4322C85: nsnadoconn (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x431D2D7: nsnaconn (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x42B1F0A: nscall (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x4357D79: niotns (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== Address 0x5EB2478 is 152 bytes inside a block of size 158 alloc'd ==3749== at 0x40046F2: malloc (vg_replace_malloc.c:149) ==3749== by 0x4390BB4: nacomap (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x438F3F6: nacomsn (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x4386355: na_client (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x437CFD1: naconnect (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x4322C85: nsnadoconn (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x431D2D7: nsnaconn (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x42B1F0A: nscall (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x4357D79: niotns (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x43F26C4: nigcall (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x4363477: osncon (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== by 0x41E42B7: kpuadef (in /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1) ==3749== ==3749== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- y starting debugger ==3749== starting debugger with cmd: $s/packages/install/bin/gdb -nw /proc/3803/fd/16374 3803 GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"... Finished Loading Init File Using host libthread_db library "/lib/tls/libthread_db.so.1". Attaching to program: /proc/3803/fd/16374, process 3803 Reading symbols from /net/stadd24/scratch/kneel/packages/install/lib/valgrind/x86-linux/vgpreload_core.so...done. Loaded symbols for /net/stadd24/scratch/kneel/packages/install/lib/valgrind/x86-linux/vgpreload_core.so Reading symbols from /net/stadd24/scratch/kneel/packages/install/lib/valgrind/x86-linux/vgpreload_memcheck.so...done. Loaded symbols for /net/stadd24/scratch/kneel/packages/install/lib/valgrind/x86-linux/vgpreload_memcheck.so Reading symbols from /usr/lib/libcwait.so...done. Loaded symbols for /usr/lib/libcwait.so Reading symbols from /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libclntsh.so.11.1...done. Loaded symbols for /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 Reading symbols from /scratch/kneel/view_storage/kneel_l1/oracle/.dispatch/lib/libnnz11.so...done. Loaded symbols for /ade/kneel_l1/oracle/lib/libnnz11.so Reading symbols from /scratch/kneel/view_storage/kneel_l1/rdbms/lib/libskgxp11.so...done. Loaded symbols for /ade/kneel_l1/rdbms/lib/libskgxp11.so Reading symbols from /lib/libdl.so.2...done. Loaded symbols for /lib/libdl.so.2 Reading symbols from /lib/tls/libm.so.6...done. Loaded symbols for /lib/tls/libm.so.6 Reading symbols from /lib/tls/libpthread.so.0...done. [Thread debugging using libthread_db enabled] [New Thread 96344288 (LWP 3749)] Loaded symbols for /lib/tls/libpthread.so.0 Reading symbols from /lib/libnsl.so.1...done. Loaded symbols for /lib/libnsl.so.1 Reading symbols from /lib/tls/libc.so.6...done. Loaded symbols for /lib/tls/libc.so.6 Reading symbols from /usr/lib/libaio.so.1...done. Loaded symbols for /usr/lib/libaio.so.1 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 Reading symbols from /usr/lib/libnuma.so...done. Loaded symbols for /usr/lib/libnuma.so Reading symbols from /scratch/kneel/view_storage/kneel_l1/oracle/.dispatch/lib/libnque11.so...done. Loaded symbols for /ade/kneel_l1/oracle/lib/libnque11.so 0x048cb638 in movdqa8 () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 (gdb) where #0 0x048cb638 in movdqa8 () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #1 0x05eb23e0 in ?? () #2 0x05e72a18 in ?? () #3 0x0592a04c in ?? () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #4 0x048c9f5d in _intel_fast_memcpy.J () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #5 0x042c1b75 in nsdo () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #6 0x043d8548 in nsbasic_sd () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #7 0x043d877b in nssend () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #8 0x0432b56f in nsnasend () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #9 0x0438f43f in nacomsn () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #10 0x04386356 in na_client () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #11 0x0437cfd2 in naconnect () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #12 0x04322c86 in nsnadoconn () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #13 0x0431d2d8 in nsnaconn () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #14 0x042b1f0b in nscall () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #15 0x04357d7a in niotns () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #16 0x043f26c5 in nigcall () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #17 0x04363478 in osncon () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #18 0x041e42b8 in kpuadef () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #19 0x041d3034 in upiini () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #20 0x041cebfe in upiah0 () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #21 0x041e39a3 in kpuatch () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #22 0x04aa54f0 in kpuspsessionget () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #23 0x0493d2c4 in OCISessionGet () from /ade/kneel_l1/rdbms/lib/libclntsh.so.11.1 #24 0x08049083 in main (argc=1, argv=0xbeff71b4) at tkpgqc17c.c:162 > doesn't need a PLT entry, and calls it drectly. Is there any way to make
> valgrind smart enough to recognize this situation?
I can't think of a way to fix this that doesn't burden the rest of Memcheck
with large extra performance overheads. Any way you slice it, reading
beyond the end of allocated blocks is a violation of POSIX and really
icc shouldn't produce code that does it (regardless of the fact that
in this particular case it's cleverly done so it won't generate any
exceptions which wouldn't have happened anyway).
Reduce optimisation level? Use a different compiler?
|