|
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). |