|
From: Norman G. <no...@te...> - 2013-07-04 19:36:06
Attachments:
smime.p7s
|
I am using valgrind-3.8.1 on Fedora 18, 32 bit x86, and am linking fortran libraries to my main C++ code. It seems that when malloc'd values end up being initialized in fortran code, that this is still tagged by valgrind as uninitialized data. I have worked around (avoided) this problem by initializing new memory to 0. I have seen related posts on the net, but am not sure if this is already flagged as a bug, or if I am not using valgrind correctly with fortran. |
|
From: Norman G. <no...@te...> - 2013-07-07 18:17:03
Attachments:
smime.p7s
|
On 07/04/2013 12:35 PM, Norman Goldstein wrote: > I am using valgrind-3.8.1 on Fedora 18, 32 bit x86, and > am linking fortran libraries to my main C++ code. > It seems that when malloc'd values end up being initialized > in fortran code, that this is still tagged by valgrind as > uninitialized data. I have worked around (avoided) this problem > by initializing new memory to 0. I have seen related posts on the > net, but am not sure if this is already flagged as a bug, or if I > am not using valgrind correctly with fortran. > Here is an update to the problem I am experiencing. While preparing a simplified build & source code example, I found that my link line was causing the problem, but I do not understand why. Here is a stylized link line that results in an executable with the described problem. gcc tsvd3.o -o tsvd3 -l:/libHigh.so -l:/libblasB.a -l:/libblas.so -l:/liblapack.so I am using -l: rather than -l because I was using debug versions of libraries in different locations, but I was not able to get the debug-info packages to work in the intended seamless way. Removing either the High or blasB library ( or both) from the link line results in no errors being reported by valgrind. This raises the following questions: -- The High library is not being referenced by the tsvd3 executable, so why does the map file show that the blasB library is being used to resolve references in the High library? -- In the above link line, the lapack library comes at the end. I thought that this would cause the lapack library not to see the blas symbols earlier in the link line i.e. the linker should be complaining about unresolved symbols. Why is the linker not so complaining? -- Why is the linker not complaining about doubly defined symbols in the blasB.a and blas.so libraries? Of course, how does all this trick valgrind into flagging uninitialized memory locations? The output of the svd3 program is correct with both versions of the tsvd3 executable. |
|
From: John R. <jr...@bi...> - 2013-07-07 20:17:20
|
> gcc tsvd3.o -o tsvd3 -l:/libHigh.so -l:/libblasB.a -l:/libblas.so -l:/liblapack.so > > I am using -l: rather than -l because I was using debug versions > of libraries in different locations, but I was not able to get the > debug-info packages to work in the intended seamless way. > > Removing either the High or blasB library ( or both) from the link > line results in no errors being reported by valgrind. > This raises the following questions: > > -- The High library is not being referenced by the tsvd3 executable, so > why does the map file show that the blasB library is being used to > resolve references in the High library? Consult the output from "readelf --dynamic tsvd3". Naming a .so shared library on the command line generates a [DT_]NEEDED entry in the Dynamic table of the executable, so that shared library is *required* at execution time. The .so is not optional, even if the .so satisfies no undefined references at static link time. At static link time (during the running of /bin/ld), any undefined symbols of the .so get added to the set which ld will try to satisfy. Thus ld will search for any symbols which are undefined in libHigh.so, and if some .o in libblasB.a defines such a symbol, then ld will load that .o from libblasB.a into tsvd3. > > -- In the above link line, the lapack library comes at the end. I thought > that this would cause the lapack library not to see the blas symbols > earlier in the link line i.e. the linker should be complaining about > unresolved symbols. Why is the linker not so complaining? The search procedure for symbols which are undefined in shared library liblapack.so is an amalgamation of the [DT_]NEEDED entries within liblapack.so, the module tsvd3 (including its [DT_]NEEDED entries), any .a archive libraries that are specified on the command line at static link time, any -Rpath specifications, and the value of environment variable LD_LIBRARY_PATH. There are different rules between static link time and dynamic run time. Read the documentation carefully (info ld, man ld, etc.) > > -- Why is the linker not complaining about doubly defined symbols > in the blasB.a and blas.so libraries? "Doubly defined" pertains only to within one module (main program or shared library.) Separate modules can have definitions of the same symbol without complaint. Which symbol gets used depends on the search path, and the search path depends scope rules at both static link time (/bin/ld) and run time (dynamic link time, ld-linux.so) > > Of course, how does all this trick valgrind into flagging uninitialized > memory locations? The output of the svd3 program is correct with > both versions of the tsvd3 executable. Construct the smallest example which causes trouble. Post it here. |
|
From: Norman G. <no...@te...> - 2013-07-08 19:01:30
|
On 07/07/2013 01:18 PM, John Reiser wrote: >> gcc tsvd3.o -o tsvd3 -l:/libHigh.so -l:/libblasB.a -l:/libblas.so -l:/liblapack.so >> >> I am using -l: rather than -l because I was using debug versions >> of libraries in different locations, but I was not able to get the >> debug-info packages to work in the intended seamless way. >> >> Removing either the High or blasB library ( or both) from the link >> line results in no errors being reported by valgrind. >> This raises the following questions: >> >> -- The High library is not being referenced by the tsvd3 executable, so >> why does the map file show that the blasB library is being used to >> resolve references in the High library? > Consult the output from "readelf --dynamic tsvd3". > > Naming a .so shared library on the command line generates a [DT_]NEEDED entry > in the Dynamic table of the executable, so that shared library is *required* > at execution time. The .so is not optional, even if the .so satisfies no undefined > references at static link time. At static link time (during the running of /bin/ld), > any undefined symbols of the .so get added to the set which ld will try to satisfy. > Thus ld will search for any symbols which are undefined in libHigh.so, > and if some .o in libblasB.a defines such a symbol, then ld will load that .o > from libblasB.a into tsvd3. > >> -- In the above link line, the lapack library comes at the end. I thought >> that this would cause the lapack library not to see the blas symbols >> earlier in the link line i.e. the linker should be complaining about >> unresolved symbols. Why is the linker not so complaining? > The search procedure for symbols which are undefined in shared library > liblapack.so is an amalgamation of the [DT_]NEEDED entries within liblapack.so, > the module tsvd3 (including its [DT_]NEEDED entries), any .a archive libraries > that are specified on the command line at static link time, any -Rpath specifications, > and the value of environment variable LD_LIBRARY_PATH. There are different > rules between static link time and dynamic run time. Read the documentation > carefully (info ld, man ld, etc.) > >> -- Why is the linker not complaining about doubly defined symbols >> in the blasB.a and blas.so libraries? > "Doubly defined" pertains only to within one module (main program or shared library.) > Separate modules can have definitions of the same symbol without complaint. > Which symbol gets used depends on the search path, and the search path > depends scope rules at both static link time (/bin/ld) and run time > (dynamic link time, ld-linux.so) > >> Of course, how does all this trick valgrind into flagging uninitialized >> memory locations? The output of the svd3 program is correct with >> both versions of the tsvd3 executable. > Construct the smallest example which causes trouble. Post it here. > > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by Windows: > > Build for Windows Store. > > http://p.sf.net/sfu/windows-dev2dev > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users > Thank you for the helpful explanations. Attached are two C++ source files that illustrate the problem I have described. The build of the tsvd3 executable is: gcc -g -c gemv2.cpp gcc -g -c tsvd3.cpp gcc -g gemv2.o tsvd3.o -llapack -lblas -lstdc++ -o tsvd3 -Wl,-y,dgemv_ NOTES: 1) Rather than linking exactly as above, I used debug versions of lapack and blas so I could explore with gdb. 2) The output from the link tells about dgemv_ for this executable: gemv2.o: definition of dgemv_ /usr/lib/gcc/i686-redhat-linux/4.7.2/../../../liblapack.so: reference to dgemv_ /usr/lib/gcc/i686-redhat-linux/4.7.2/../../../libblas.so: reference to dgemv_ The gemv2.cpp is a slash and contract of (some of) the very well written and organized source code of the FLENS numerical linear algebra package. My apologies to FLENS for having to distort their handiwork for this purpose :-). Initially, I had thought that fortran was initializing the memory, since the routine is called dgemv_, but it turns out I was using a FLENS option that implements this routine in C++, as in the atached gemv2.cpp . So, the fortran lapack and blas libraries are calling the C++ routine dgemv_. Might this be confusing to valgrind?? The running of tsvd3 gives the values: VS= 6.25801 4.91733 3.72567 2.98619 (I think these are not the correct singular values, but this is not relevant to valgrind issue) I ran valgrind: valgrind --track-origins=yes --fullpath-after= ./tsvd3 The first reported error is ==18263== Conditional jump or move depends on uninitialised value(s) ==18263== at 0x433B99F: iladlr_ (/usr/src/debug/lapack-3.4.2/SRC/iladlr.f:107) ==18263== by 0x4287CEE: dlarf_ (/usr/src/debug/lapack-3.4.2/SRC/dlarf.f:187) ==18263== by 0x4202FC9: dgelq2_ (/usr/src/debug/lapack-3.4.2/SRC/dgelq2.f:184) ==18263== by 0x4203624: dgelqf_ (/usr/src/debug/lapack-3.4.2/SRC/dgelqf.f:262) ==18263== by 0x4216632: dgesdd_ (/usr/src/debug/lapack-3.4.2/SRC/dgesdd.f:1055) ==18263== by 0x8049559: main (/home/norm17b/dev/src/ssrd/test/lor/tsvd3.cpp:61) ==18263== Uninitialised value was created by a heap allocation ==18263== at 0x4008449: operator new[](unsigned int) (/builddir/build/BUILD/valgrind-3.8.1/coregrind/m_replacemalloc/vg_replace_malloc.c:357) ==18263== by 0x80494BA: main (/home/norm17b/dev/src/ssrd/test/lor/tsvd3.cpp:52) The line in main() that allocates the memory is double* work = new double[ lwork ]; where lwork= 300 This is a typical work array in the style of lapack. Next, I stepped into iladr through the above chain, and set a breakpoint at iladr.f:107 ELSE IF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN ILADLR = M Examining memory, p m p n p lda x/Kfg &a where K = lda * n I found that the mxn submatrix was always initialized at all its entries. I did this several times, until "gdb continue" resulted in the program completing (because of looping, the breakpoint re-occurred several times). This is why I am puzzled as to why valgrind is reporting uninitialised value(s). |
|
From: John R. <jr...@bi...> - 2013-07-09 05:24:33
|
> I found that the mxn submatrix was always initialized at all its > entries. I did this several times, until "gdb continue" resulted > in the program completing (because of looping, the breakpoint > re-occurred several times). > > This is why I am puzzled as to why valgrind is reporting uninitialised value(s). Thank you for the test case. After installing lapack and blas (Fedora 17), then I see the behavior you describe. I did not get the corresponding debuginfo versions, so I have not seen inside iladr. What I did do is binary search on: ----- tsvd3.cpp // Elliminate spurious valgrind uninitialized errors #if 1 for( int iii=38; iii<lwork; ++iii ) work[iii]=123.456; #endif ----- I see no complaints when starting the loop at iii=1,2,4,8,16,32; then errors at 64,48,40; no complaint at 36; errors at 38; no complaint at 37. Hmmm... At this point it's at least somewhat reasonable to file a bug report and include the test case. The rejoinder will be that memcheck finds a real error, and the code "Eliminate ... uninit errors" is the proof. I'm not so sure. I did notice that all the complaints on x86_64 are after a 'ucomisd' instruction where the low 64 bits of the register have a double floating point value, with the high 64 bits being zero. When the other operand to ucomids also is a register, then that register often has all bits zero (128 zero bits). In most ways the operating width is 64 bits, yet the register has 128 bits. -- |
|
From: John R. <jr...@bi...> - 2013-07-09 20:15:50
|
> What I did do is binary search on: > ----- tsvd3.cpp > // Elliminate spurious valgrind uninitialized errors > #if 1 > for( int iii=38; iii<lwork; ++iii ) work[iii]=123.456; > #endif > ----- > I see no complaints when starting the loop at iii=1,2,4,8,16,32; > then errors at 64,48,40; no complaint at 36; errors at 38; > no complaint at 37. Hmmm... First, whenever you are faced with murky malloc, then you should enlist help. The glibc library provides some debugging aids which are quite inexpensive. They are so cheap that I use them all the time, for all processes. Put this in $HOME/.bash_profile, or feed it directly to your shell, etc.: # http://udrepper.livejournal.com/11429.html export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) echo 1>&2 MALLOC_PERTURB_=$MALLOC_PERTURB_ " # $HOME/.bash_profile" This will cause all bytes in newly malloc()ed areas to be set to the same random byte. [Or, specify a constant such as export MALLOC_PERTURB_=0xF5 When running under valgrind, then the low-level interception of malloc() and the careful watching by memcheck will supersede MALLOC_PERTURB_.] Continuing after the binary search, I tried: ----- tsvd3.cpp // Elliminate spurious valgrind uninitialized errors #if 1 for( int iii=38; iii<lwork; ++iii ) work[iii]=123.456; for( int iii= 1; iii<= 36; ++iii ) work[iii]=123.456; #endif ----- which leaves only work[37] uninit. Running this under valgrind generates complaints from memcheck; the first is: ----- lwork_q= 108 lwork= 108 ==23901== Conditional jump or move depends on uninitialised value(s) ==23901== at 0x5498486: dnrm2_ (/usr/src/debug/lapack-3.4.2/BLAS/SRC/dnrm2.f:94) ==23901== by 0x4E27E27: dlarfg_ (in /usr/lib64/atlas/liblapack.so.3.0) ==23901== by 0x4DACD89: dgelq2_ (in /usr/lib64/atlas/liblapack.so.3.0) ==23901== by 0x4DAD457: dgelqf_ (in /usr/lib64/atlas/liblapack.so.3.0) ==23901== by 0x4DBA96B: dgesdd_ (in /usr/lib64/atlas/liblapack.so.3.0) ==23901== by 0x4018F7: main (/bigdata/home/jreiser/valgrind-fortran/tsvd3.cpp:62) ==23901== Uninitialised value was created by a heap allocation ==23901== at 0x4A07C84: operator new[](unsigned long) (/builddir/build/BUILD/valgrind-3.8.1/coregrind/m_replacemalloc/vg_replace_malloc.c:363) ==23901== by 0x40180F: main (/bigdata/home/jreiser/valgrind-fortran/tsvd3.cpp:52) ----- Now we know that exactly one 8-byte 'double' uninit at work[37] will trigger the complaints. This aligned 8-byte region is small enough that we can take advantage of debugging hardware in x86 chips. So now I run directly under gdb (without valgrind), put a breakpoint just after the code which leaves work[37] uninit, and plant a hardware 'read' watchpoint on &work[37]: (gdb) b tsvd3.cpp:58 (gdb) run Breakpoint 2, main () at tsvd3.cpp:62 (gdb) p &work[37] $1 = (double *) 0x606178 (gdb) rwatch *(double *)0x606178 Hardware read watchpoint 3: *(double *)0x606178 (gdb) continue Lo and behold, work[37] is fetched and used. That is, there is a real error: Hardware read watchpoint 3: *(double *)0x606178 Value = -1.6882786079646144e+260 0x000000000040154a in scal_generic<int, double, double> (n=0x3, alpha=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:17 17 y[iY] *= alpha; (gdb) x/12i $pc-0x18 0x401532 <scal_generic<int, double, double>(int, double const&, double*, int)+54>: mov -0x8(%rbp),%eax 0x401535 <scal_generic<int, double, double>(int, double const&, double*, int)+57>: cltq 0x401537 <scal_generic<int, double, double>(int, double const&, double*, int)+59>: lea 0x0(,%rax,8),%rcx 0x40153f <scal_generic<int, double, double>(int, double const&, double*, int)+67>: mov -0x28(%rbp),%rax 0x401543 <scal_generic<int, double, double>(int, double const&, double*, int)+71>: add %rcx,%rax 0x401546 <scal_generic<int, double, double>(int, double const&, double*, int)+74>: movsd (%rax),%xmm1 ### the fetch of uninit => 0x40154a <scal_generic<int, double, double>(int, double const&, double*, int)+78>: mov -0x20(%rbp),%rax 0x40154e <scal_generic<int, double, double>(int, double const&, double*, int)+82>: movsd (%rax),%xmm0 0x401552 <scal_generic<int, double, double>(int, double const&, double*, int)+86>: mulsd %xmm1,%xmm0 ### the use of uninit 0x401556 <scal_generic<int, double, double>(int, double const&, double*, int)+90>: movsd %xmm0,(%rdx) 0x40155a <scal_generic<int, double, double>(int, double const&, double*, int)+94>: addl $0x1,-0x4(%rbp) 0x40155e <scal_generic<int, double, double>(int, double const&, double*, int)+98>: mov -0x18(%rbp),%eax (gdb) p $rax $2 = 0x606178 ### yes, it is &work[37] (gdb) x/2xw $rax ### and those bytes are uninit 0x606178: 0xf5f5f5f5 0xf5f5f5f5 ### The pattern for uninit set by MALLOC_PERTURB_ (gdb) bt #0 0x000000000040154a in scal_generic<int, double, double> (n=0x3, alpha=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:17 #1 0x00000000004011f8 in gemv_generic<int, double, double, double, double, double> (order=RowMajor, transA=Trans, conjX=NoTrans, m=0x8, n=0x3, alpha=@0x7ffff7ca6bc8: 1, A=0x7fffffffde48, ldA=0x4, x=0x7fffffffde40, incX=0x4, beta=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:108 #2 0x0000000000400e05 in gemv_generic<int, double, double, double, double, double> (order=ColMajor, transA=Trans, conjX=NoTrans, m=0x3, n=0x8, alpha=@0x7ffff7ca6bc8: 1, A=0x7fffffffde48, ldA=0x4, x=0x7fffffffde40, incX=0x4, beta=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:58 #3 0x0000000000400d4e in gemv<int, double, double, double, double, double> ( order=ColMajor, trans=NoTrans, m=0x3, n=0x8, alpha=@0x7ffff7ca6bc8: 1, A=0x7fffffffde48, ldA=0x4, x=0x7fffffffde40, incX=0x4, beta=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:156 #4 0x0000000000400cc8 in dgemv_ (TRANS=0x7ffff7ca6be8 "No transpose", M=0x7fffffffd938, N=0x7fffffffd93c, ALPHA=0x7ffff7ca6bc8, _A=0x7fffffffde48, LDA=0x7fffffffdf58, X=0x7fffffffde40, INCX=0x7fffffffdf58, BETA=0x7ffff7ca6be0, Y=0x606170, INCY=0x7ffff7ca6bdc) at gemv2.cpp:204 #5 0x00007ffff797f3fb in dlarf_ () from /usr/lib64/atlas/liblapack.so.3 #6 0x00007ffff7906e1f in dgelq2_ () from /usr/lib64/atlas/liblapack.so.3 #7 0x00007ffff7907458 in dgelqf_ () from /usr/lib64/atlas/liblapack.so.3 #8 0x00007ffff791496c in dgesdd_ () from /usr/lib64/atlas/liblapack.so.3 #9 0x00000000004018f8 in main () at tsvd3.cpp:62 So there is the [a] real error. Apologize to memcheck, and fix your bug. |
|
From: John R. <jr...@bi...> - 2013-07-10 17:01:16
|
> # http://udrepper.livejournal.com/11429.html > export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) > echo 1>&2 MALLOC_PERTURB_=$MALLOC_PERTURB_ " # $HOME/.bash_profile" > This will cause all bytes in newly malloc()ed areas to be set to the > same random byte. [Or, specify a constant such as > export MALLOC_PERTURB_=0xF5 The current implementation within glibc-2.17 uses (0xff & (0xff ^ atoi(getenv("MALLOC_PERTURB_")))) so you suffer the vagaries of atoi() and a bit-wise complement. |
|
From: Norman G. <no...@te...> - 2013-07-09 22:42:56
Attachments:
smime.p7s
|
On 07/09/2013 01:16 PM, John Reiser wrote: >> What I did do is binary search on: >> ----- tsvd3.cpp >> // Elliminate spurious valgrind uninitialized errors >> #if 1 >> for( int iii=38; iii<lwork; ++iii ) work[iii]=123.456; >> #endif >> ----- >> I see no complaints when starting the loop at iii=1,2,4,8,16,32; >> then errors at 64,48,40; no complaint at 36; errors at 38; >> no complaint at 37. Hmmm... > First, whenever you are faced with murky malloc, then you should enlist help. > The glibc library provides some debugging aids which are quite inexpensive. > They are so cheap that I use them all the time, for all processes. > Put this in $HOME/.bash_profile, or feed it directly to your shell, etc.: > # http://udrepper.livejournal.com/11429.html > export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) > echo 1>&2 MALLOC_PERTURB_=$MALLOC_PERTURB_ " # $HOME/.bash_profile" > This will cause all bytes in newly malloc()ed areas to be set to the > same random byte. [Or, specify a constant such as > export MALLOC_PERTURB_=0xF5 > When running under valgrind, then the low-level interception of malloc() > and the careful watching by memcheck will supersede MALLOC_PERTURB_.] > > Continuing after the binary search, I tried: > ----- tsvd3.cpp > // Elliminate spurious valgrind uninitialized errors > #if 1 > for( int iii=38; iii<lwork; ++iii ) work[iii]=123.456; > for( int iii= 1; iii<= 36; ++iii ) work[iii]=123.456; > #endif > ----- > which leaves only work[37] uninit. Running this under valgrind > generates complaints from memcheck; the first is: > ----- > lwork_q= 108 > lwork= 108 > ==23901== Conditional jump or move depends on uninitialised value(s) > ==23901== at 0x5498486: dnrm2_ (/usr/src/debug/lapack-3.4.2/BLAS/SRC/dnrm2.f:94) > ==23901== by 0x4E27E27: dlarfg_ (in /usr/lib64/atlas/liblapack.so.3.0) > ==23901== by 0x4DACD89: dgelq2_ (in /usr/lib64/atlas/liblapack.so.3.0) > ==23901== by 0x4DAD457: dgelqf_ (in /usr/lib64/atlas/liblapack.so.3.0) > ==23901== by 0x4DBA96B: dgesdd_ (in /usr/lib64/atlas/liblapack.so.3.0) > ==23901== by 0x4018F7: main (/bigdata/home/jreiser/valgrind-fortran/tsvd3.cpp:62) > ==23901== Uninitialised value was created by a heap allocation > ==23901== at 0x4A07C84: operator new[](unsigned long) (/builddir/build/BUILD/valgrind-3.8.1/coregrind/m_replacemalloc/vg_replace_malloc.c:363) > ==23901== by 0x40180F: main (/bigdata/home/jreiser/valgrind-fortran/tsvd3.cpp:52) > ----- > Now we know that exactly one 8-byte 'double' uninit at work[37] will trigger the complaints. > This aligned 8-byte region is small enough that we can take advantage of debugging hardware > in x86 chips. > > So now I run directly under gdb (without valgrind), put a breakpoint just after > the code which leaves work[37] uninit, and plant a hardware 'read' watchpoint on &work[37]: > (gdb) b tsvd3.cpp:58 > (gdb) run > Breakpoint 2, main () at tsvd3.cpp:62 > (gdb) p &work[37] > $1 = (double *) 0x606178 > (gdb) rwatch *(double *)0x606178 > Hardware read watchpoint 3: *(double *)0x606178 > (gdb) continue > > > Lo and behold, work[37] is fetched and used. That is, there is a real error: > Hardware read watchpoint 3: *(double *)0x606178 > > Value = -1.6882786079646144e+260 > 0x000000000040154a in scal_generic<int, double, double> (n=0x3, > alpha=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:17 > 17 y[iY] *= alpha; > (gdb) x/12i $pc-0x18 > 0x401532 <scal_generic<int, double, double>(int, double const&, double*, int)+54>: mov -0x8(%rbp),%eax > 0x401535 <scal_generic<int, double, double>(int, double const&, double*, int)+57>: cltq > 0x401537 <scal_generic<int, double, double>(int, double const&, double*, int)+59>: lea 0x0(,%rax,8),%rcx > 0x40153f <scal_generic<int, double, double>(int, double const&, double*, int)+67>: mov -0x28(%rbp),%rax > 0x401543 <scal_generic<int, double, double>(int, double const&, double*, int)+71>: add %rcx,%rax > 0x401546 <scal_generic<int, double, double>(int, double const&, double*, int)+74>: movsd (%rax),%xmm1 ### the fetch of uninit > => 0x40154a <scal_generic<int, double, double>(int, double const&, double*, int)+78>: mov -0x20(%rbp),%rax > 0x40154e <scal_generic<int, double, double>(int, double const&, double*, int)+82>: movsd (%rax),%xmm0 > 0x401552 <scal_generic<int, double, double>(int, double const&, double*, int)+86>: mulsd %xmm1,%xmm0 ### the use of uninit > 0x401556 <scal_generic<int, double, double>(int, double const&, double*, int)+90>: movsd %xmm0,(%rdx) > 0x40155a <scal_generic<int, double, double>(int, double const&, double*, int)+94>: addl $0x1,-0x4(%rbp) > 0x40155e <scal_generic<int, double, double>(int, double const&, double*, int)+98>: mov -0x18(%rbp),%eax > > (gdb) p $rax > $2 = 0x606178 ### yes, it is &work[37] > (gdb) x/2xw $rax ### and those bytes are uninit > 0x606178: 0xf5f5f5f5 0xf5f5f5f5 ### The pattern for uninit set by MALLOC_PERTURB_ > (gdb) bt > #0 0x000000000040154a in scal_generic<int, double, double> (n=0x3, > alpha=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:17 > #1 0x00000000004011f8 in gemv_generic<int, double, double, double, double, double> (order=RowMajor, transA=Trans, conjX=NoTrans, m=0x8, n=0x3, > alpha=@0x7ffff7ca6bc8: 1, A=0x7fffffffde48, ldA=0x4, x=0x7fffffffde40, > incX=0x4, beta=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:108 > #2 0x0000000000400e05 in gemv_generic<int, double, double, double, double, double> (order=ColMajor, transA=Trans, conjX=NoTrans, m=0x3, n=0x8, > alpha=@0x7ffff7ca6bc8: 1, A=0x7fffffffde48, ldA=0x4, x=0x7fffffffde40, > incX=0x4, beta=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:58 > #3 0x0000000000400d4e in gemv<int, double, double, double, double, double> ( > order=ColMajor, trans=NoTrans, m=0x3, n=0x8, alpha=@0x7ffff7ca6bc8: 1, > A=0x7fffffffde48, ldA=0x4, x=0x7fffffffde40, incX=0x4, > beta=@0x7ffff7ca6be0: 0, y=0x606170, incY=0x1) at gemv2.cpp:156 > #4 0x0000000000400cc8 in dgemv_ (TRANS=0x7ffff7ca6be8 "No transpose", > M=0x7fffffffd938, N=0x7fffffffd93c, ALPHA=0x7ffff7ca6bc8, > _A=0x7fffffffde48, LDA=0x7fffffffdf58, X=0x7fffffffde40, > INCX=0x7fffffffdf58, BETA=0x7ffff7ca6be0, Y=0x606170, INCY=0x7ffff7ca6bdc) > at gemv2.cpp:204 > #5 0x00007ffff797f3fb in dlarf_ () from /usr/lib64/atlas/liblapack.so.3 > #6 0x00007ffff7906e1f in dgelq2_ () from /usr/lib64/atlas/liblapack.so.3 > #7 0x00007ffff7907458 in dgelqf_ () from /usr/lib64/atlas/liblapack.so.3 > #8 0x00007ffff791496c in dgesdd_ () from /usr/lib64/atlas/liblapack.so.3 > #9 0x00000000004018f8 in main () at tsvd3.cpp:62 > > So there is the [a] real error. Apologize to memcheck, and fix your bug. > > > ------------------------------------------------------------------------------ > See everything from the browser to the database with AppDynamics > Get end-to-end visibility with application monitoring from AppDynamics > Isolate bottlenecks and diagnose root cause in seconds. > Start your free trial of AppDynamics Pro today! > http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users > Thank you for the detailed analysis and explanation of techniques! This example also shows that the memcheck error descriptions should be taken with a grain of salt i.e. the error may be occurring elsewhere, and not where the error description is suggesting. Is this the nature of the beast, or can memcheck be more accurate in locating the errors? PS work[0] was also left uninitialized :-) |
|
From: John R. <jr...@bi...> - 2013-07-09 23:41:40
|
> This example also shows that the memcheck error descriptions should > be taken with a grain of salt i.e. the error may be occurring elsewhere, and > not where the error description is suggesting. Is this the nature of the beast, > or can memcheck be more accurate in locating the errors? Memcheck has decided not to complain unless the uninit affects control flow, file output, or an index expression for array access. This is motivated by an attempt to reduce "false positive" complaints: those that "do not affect the output", and thus "the user does not care about them." If there are too many false positive complaints, then users quickly ignore *ALL* complaints (that is, the user discards memcheck as not useful.) Also, alignment and padding in 'struct's often result in uninit "holes" that are copied indiscriminately, and often the end programmer cannot do anything about these because those holes were specified as part of some inner ABI. Also, gcc tends to "overfetch" scalar char and short operands (fetches 32 bits regardless of actual length being 16 or 8), and the overage often is uninit. *UNFORTUNATELY*, memcheck's policy of complaining "as late as possible" means that serious users often experience a really tough debugging chore because the source of the error happens very much earlier than the complaint. It would be much nicer if memcheck had the *OPTION* to complain "as soon as possible": namely, as soon as any uninit bits are fetched from memory. The serious user will either fix the holes in alignment and padding, or write suppressions, or otherwise ignore what is not interesting at the moment, in order to eradicate the *source* of the uninit-of-the-moment. But the implementers of memcheck are not yet convinced. |
|
From: Philippe W. <phi...@sk...> - 2013-07-08 15:34:43
|
On Thu, 2013-07-04 at 12:35 -0700, Norman Goldstein wrote: > I am using valgrind-3.8.1 on Fedora 18, 32 bit x86, and > am linking fortran libraries to my main C++ code. > It seems that when malloc'd values end up being initialized > in fortran code, that this is still tagged by valgrind as > uninitialized data. I have worked around (avoided) this problem > by initializing new memory to 0. I have seen related posts on the > net, but am not sure if this is already flagged as a bug, or if I > am not using valgrind correctly with fortran. If you know at what place(s) the fortran code is supposed to initialise the memory, you could use gdb/vgdb, put a break at this place(s), and then verify that the "v bits" of the "source memory" used to initialise the target memory are effectively what is expected (i.e. that the fortran code is copying "initialised" values to this memory. This might point at some locations that fortran assumes are initialised but valgrind did not track such initialisation. Using --track-origins=yes might also help to pinpoint a possible error. Philippe |