I want to use valgrind to see if my program has memory errors.
I want to run the program on Alpine linux which has different standard c library (musl vs glibc).
Here is and example output on "echo" command with valgrind on the Alpine linux:
/ # valgrind echo "hi"
==480== Memcheck, a memory error detector
==480== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==480== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info
==480== Command: echo hi
==480==
hi
==480==
==480== HEAP SUMMARY:
==480== in use at exit: 0 bytes in 0 blocks
==480== total heap usage: 1 allocs, 1 frees, 4 bytes allocated
==480==
==480== All heap blocks were freed -- no leaks are possible
==480==
==480== For lists of detected and suppressed errors, rerun with: -s
==480== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
As expected there are no problems in "echo" program.
When I run my program with valgrind on Alpine (passing--track-origins=yes, --leak-check=full doesn't cause any change):
/ # valgrind work/test_lib
==481== Memcheck, a memory error detector
==481== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==481== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info
==481== Command: work/test_lib
==481==
Please pass path to lib + config + (optional data_json) (optional output path)
/ #
The summary is missing. I don't see any errors. The program itself is very simple - just prints the lines after checking the program didn't receive 2 input parameters. Also when I run the program with arguments, it runs correctly and prints the right output result. There is no valgrind summary output after program ends in both cases.
In the other machine (Centos) valgrind indeed print valgrind summary output in the end (which is clean of problems).
The program was complied with gcc-4.8 and glibc, but without any special dependencies:
g++ -Wall --std=c++11 -ldl -march=x86-64 -msse2 -msse3 -msse4 test_lib.cpp -o test_lib
/ # ldd work/test_lib
/lib64/ld-linux-x86-64.so.2 (0x7fc52c31b000)
libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7fc52c31b000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7fc52c0cd000)
libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fc52c31b000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7fc52c0af000)
libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fc52c31b000)
I was expecting to see valgrind summary report after running my program with valgrind on Alpine linux.
OK,
The code that is being executed is:
if (argc <= 2) { printf("Please pass path to lib + ...\n"); return -1; }
I don't see a reason to add "--trace-children=yes" to cause valgrind to work in this case.
But Alpine (since it was compiled with glibc) causes this to create a child process. Adding "--trace-children=yes" solves the problem in Alpine for programs that were compiled with glibc.
I tried to track the "child" process using ps -ef | more
valgrind --trace-children=yes /lib/ld-musl-x86_64.so.1 --argv0
./test_lib --preload /lib/libgcompat.so.0
/usr/libexec/valgrind/vgpreload_core-amd64-linux.so:/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so
-- /work/test_lib
when running "valgrind echo hi", I don't see all those "--preload"
Related
Q. How to cross compile valgrind for ARM on x86 ubuntu machine ?
Here is a self-contained procedure, assuming you are building on a x86_64 Ubuntu Linux machine. If this is not the case, just install the cross-compiler for the arm-none-linux-gnueabihf target available from your Linux distribution, make sure it is in your path, and modify the configure command accordingly.
On the PC side:
# downloading/installing toolchain
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.2-2020.11/binrel/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz?revision=d0b90559-3960-4e4b-9297-7ddbc3e52783&la=en&hash=985078B758BC782BC338DB947347107FBCF8EF6B
sudo mkdir -p /opt/arm/10
sudo tar Jxf gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz -C /opt/arm/10
# downloading/extracting valgrind
wget https://sourceware.org/pub/valgrind/valgrind-3.16.1.tar.bz2
tar jxf valgrind-3.16.1.tar.bz2
# building
export PATH=/opt/arm/10/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin:$PATH
mdkir valgrind
cd valgrind
../valgrind-3.16.1/configure --host=arm-none-linux-gnueabihf --prefix=$(pwd)/valgrind-3.16.1-arm-none-linux-gnueabihf
make all install
On the Orangepi:
Copy the content of the valgrind-3.16.1-arm-none-linux-gnueabihf directory and its sub-directories from your PC into the /usr/local directory of your Orangepi.
Install libc6-dbg (assuming you are running Ubuntu or Debian on your Orangepi): apt-get install libc6-dbg
test using the procedure provide here:
wget http://cs.ecs.baylor.edu/~donahoo/tools/valgrind/test.c
gcc -o test -g test.c
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./test
==2034== Memcheck, a memory error detector
==2034== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2034== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==2034== Command: ./test
==2034==
==2034==
==2034== FILE DESCRIPTORS: 3 open at exit.
==2034== Open file descriptor 2: /dev/ttyS0
==2034== <inherited from parent>
==2034==
==2034== Open file descriptor 1: /dev/ttyS0
==2034== <inherited from parent>
==2034==
==2034== Open file descriptor 0: /dev/ttyS0
==2034== <inherited from parent>
==2034==
==2034==
==2034== HEAP SUMMARY:
==2034== in use at exit: 35 bytes in 2 blocks
==2034== total heap usage: 3 allocs, 1 frees, 47 bytes allocated
==2034==
==2034== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==2034== at 0x484A4B0: malloc (vg_replace_malloc.c:307)
==2034== by 0x1087DB: main (test.c:15)
==2034==
==2034== 19 bytes in 1 blocks are definitely lost in loss record 2 of 2
==2034== at 0x484A4B0: malloc (vg_replace_malloc.c:307)
==2034== by 0x1087BB: main (test.c:8)
==2034==
==2034== LEAK SUMMARY:
==2034== definitely lost: 35 bytes in 2 blocks
==2034== indirectly lost: 0 bytes in 0 blocks
==2034== possibly lost: 0 bytes in 0 blocks
==2034== still reachable: 0 bytes in 0 blocks
I write a naive c program try.c
#include <stdlib.h>
int main() {return 0;}
Then I try to compile and run it with the shell script below
CFLAGS='-Wpedantic -Wall -Wextra -Werror -std=c89'
gcc -o try ${CFLAGS} try.c -static
valgrind ./try -v --track-origins=yes
Then the output is quite confusing:
==16641== Memcheck, a memory error detector
==16641== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==16641== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==16641== Command: ./try -v --track-origins=yes
==16641==
==16641== Conditional jump or move depends on uninitialised value(s)
==16641== at 0x419349: _int_free (in /home/su/ca/hw/1_try/try_static/trytrytry/try)
==16641== by 0x41D296: free (in /home/su/ca/hw/1_try/try_static/trytrytry/try)
==16641== by 0x46CCAE: fillin_rpath (in /home/su/ca/hw/1_try/try_static/trytrytry/try)
==16641== by 0x46D57A: _dl_init_paths (in /home/su/ca/hw/1_try/try_static/trytrytry/try)
==16641== by 0x44282B: _dl_non_dynamic_init (in /home/su/ca/hw/1_try/try_static/trytrytry/try)
==16641== by 0x443557: __libc_init_first (in /home/su/ca/hw/1_try/try_static/trytrytry/try)
==16641== by 0x400B77: (below main) (in /home/su/ca/hw/1_try/try_static/trytrytry/try)
However, if I remove the option "-static", everything goes well.
I tried it on ubuntu 16.04 (virtual machine ) and ubuntu 14.04 (virtual machine )
Maybe it has something to do with virtual machine ?
This error is part of a call stack that Valgrind probably suppresses by default. The suppression is specific to the shared library that the call is part of (that is, libc) -- so building your program as a static executable prevents Valgrind from recognizing that it should ignore this error.
In any event, this error is internal to libc initialization code, so you should ignore it.
I picked up a valgrind banary for qnx 6.5 and was able to run the qnx binary on a sample program as below :
# /usr/valgrind/x86/usr/bin/valgrind
valgrind: no program specified
valgrind: Use --help for more information.
# /usr/valgrind/x86/usr/bin/valgrind --version
valgrind-3.10.1
# /usr/valgrind/x86/usr/bin/valgrind --tool=memcheck
valgrind: no program specified
valgrind: Use --help for more information.
# /usr/valgrind/x86/usr/bin/valgrind --tool=memcheck ls
==6332450== Memcheck, a memory error detector
==6332450== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6332450== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==6332450== Command: ls
==6332450==
==6332450==
==6332450==
==6332450== Valgrind is exiting:
==6332450== Symbols for /proc/boot/libc.so.3 are required but not found.
==6332450== (Suggestion: compile that binary with debug-information, or provide a separate symbol-file.)
==6332450==
==6332450==
But while to run the same binary with a arm binary(code compiled on arm processor) its throwing the below error :
# /usr/valgrind1/x86/usr/bin/valgrind /usr/bt
(here bt is the binary compiled with arm)
valgrind: executable is not for this architecture
Note : /usr/valgrind_arm/valgrind/bin/valgrind ls
/usr/valgrind_arm/valgrind/bin/valgrind[1]: syntax error: `^AÜ$O4T^H' unexpected
Any suggestion or response will be highly appreciated .
Cause /proc/boot/libc.so.3 don't have debugging symbols.
Try run valgrind from current working directory /lib, that containing different version of libc.so.3 with debug symbols. Or set its path as
valgrind --tool=memcheck --extra-debuginfo-path=/lib <prog_name>
I am using the Instruments from XCode 4.2.1 to find some memory leaks.
I have found a very weird (at least for me) memory leak:
(The function values_table_get_value returns a double, and output = stdout)
The two questions are:
Is it a real memory leak?
How can I clean up it? (The fprintf format %.3f is wrong for a double?
To show that the leak is inside the fprintf, I changed the return from the function to 5.0:
and moving the return to a temporary variable:
and to be more precise, here is a picture of the asm code that shows that the leak is:
I did a very simple test: printing using the sprintf + fprintf, but I get the leak at sprintf:
I also tried to use the printf directly, and I get the leak on it.
I am really thinking that the problem is in format.
The final try, to show that do not have anything related with my function:
Just to check, I executed with valgrind: (values_table_print is the function name)
valgrind --leak-check=full --show-reachable=yes ./leastsquares
My software versions:
valgrind --version: valgrind-3.7.0
gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
Don't waste time debugging
Your setup probably has a bad gcc or valgrind build or simply isn't up-to-date.
I just tried:
gcc -o junk /tmp/junk.cpp && ~/src/valgrind/coregrind/valgrind --leak-check=full --show-reachable=yes /tmp/junk
on the following snippet
#include <stdio.h>
int main()
{
printf( "%.3f", 3.0 );
}
Configuration
OSX 10.7.2
valgrind-3.7.0.SVN
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)
Using built-in specs.
Target: i686-apple-darwin11
Configured with: /private/var/tmp/llvmgcc42/llvmgcc42-2335.15~25/src/configure --disable-checking --enable-werror --prefix=/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2335.15~25/dst-llvmCore/Developer/usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)
Valgrind Output
==58980== Memcheck, a memory error detector
==58980== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==58980== Using Valgrind-3.7.0.SVN and LibVEX; rerun with -h for copyright info
==58980== Command: /tmp/junk
==58980==
--58980-- /tmp/junk:
--58980-- dSYM directory is missing; consider using --dsymutil=yes
UNKNOWN task message [id 3229, to mach_task_self(), reply 0x2503]
UNKNOWN task message [id 3229, to mach_task_self(), reply 0x2503]
UNKNOWN task message [id 3414, to mach_task_self(), reply 0x2503]
--58980-- WARNING: unhandled syscall: unix:357
--58980-- You may be able to write your own handler.
--58980-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--58980-- Nevertheless we consider this a bug. Please report
--58980-- it at http://valgrind.org/support/bug_reports.html.
3.000==58980==
==58980== HEAP SUMMARY:
==58980== in use at exit: 0 bytes in 0 blocks
==58980== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==58980==
==58980== All heap blocks were freed -- no leaks are possible
==58980==
==58980== For counts of detected and suppressed errors, rerun with: -v
==58980== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I'm getting valgrind errors when attempting to pclose() a pipe previously open with popen(). The errors occur on Mac OS X, but not on Linux. Consider the following example:
#include <stdlib.h>
#include <stdio.h>
int main() {
FILE *fp;
char buf[4096];
if (!(fp = popen("ls", "r")))
exit(-1);
while (fscanf(fp, "%s", buf) == 1)
printf("%s\n", buf);
pclose(fp);
return 0;
}
I get the following valgrind errors on a Mac (OS X 10.6.7, valgrind version 3.6.0), except if I remove the pclose() call:
==21455== Conditional jump or move depends on uninitialised value(s)
==21455== at 0xB1992: pclose (in /usr/lib/libSystem.B.dylib)
==21455== by 0x1F16: main (in ./a.out)
==21455==
==21455== Syscall param wait4(pid) contains uninitialised byte(s)
==21455== at 0x504FA: wait4 (in /usr/lib/libSystem.B.dylib)
==21455== by 0x1F16: main (in ./a.out)
However, I don't get any errors on a Linux system with valgrind version 3.5.0.
Any ideas on what could be causing the errors on the Mac?
Update
Turning on --track-origins in valgrind shows that the origin of the problem might be in the popen() call. Got the same thing with gcc 4.2.1 and 4.5.3.
==4425== Conditional jump or move depends on uninitialised value(s)
==4425== at 0xB1992: pclose (in /usr/lib/libSystem.B.dylib)
==4425== by 0x1F18: main (in ./a.out)
==4425== Uninitialised value was created by a stack allocation
==4425== at 0xB14C5: popen$UNIX2003 (in /usr/lib/libSystem.B.dylib)
==4425==
==4425== Syscall param wait4(pid) contains uninitialised byte(s)
==4425== at 0x504FA: wait4 (in /usr/lib/libSystem.B.dylib)
==4425== by 0x1F18: main (in ./a.out)
==4425== Uninitialised value was created by a stack allocation
==4425== at 0xB14C5: popen$UNIX2003 (in /usr/lib/libSystem.B.dylib)
It is quite common for system libraries to pass uninitialized bytes to system calls. It is less common for conditional jump to depend on uninitialized value, but it does happen (glibc-2.X.supp in my Linux build contains 8 suppressions for this in glibc).
Since there is nothing you can do about these errors anyway, you should just suppress them. See --gen-suppressions in Valgrind docs.
The reported problem seems to be internal to the system library, not in your code.
I too get no errors using MacOS X 10.6.8, Valgrind 3.6.0, and either (Apple's) GCC 4.2.1 or (my) GCC 4.6.0. I do get compilation warnings from your code (4.6.0 shown) - actually, I have 'make' run the command and the makefile contains all those -Wxxx arguments:
$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition vg.c -o vg
vg.c:4:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
vg.c: In function ‘main’:
vg.c:4:5: warning: old-style function definition [-Wold-style-definition]
$ valgrind vg
==40593== Memcheck, a memory error detector
==40593== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==40593== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==40593== Command: vg
==40593==
vg
vg.c
vg.dSYM
==40593==
==40593== HEAP SUMMARY:
==40593== in use at exit: 4,184 bytes in 2 blocks
==40593== total heap usage: 6 allocs, 4 frees, 26,848 bytes allocated
==40593==
==40593== LEAK SUMMARY:
==40593== definitely lost: 0 bytes in 0 blocks
==40593== indirectly lost: 0 bytes in 0 blocks
==40593== possibly lost: 0 bytes in 0 blocks
==40593== still reachable: 4,184 bytes in 2 blocks
==40593== suppressed: 0 bytes in 0 blocks
==40593== Rerun with --leak-check=full to see details of leaked memory
==40593==
==40593== For counts of detected and suppressed errors, rerun with: -v
==40593== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ cc --version
i686-apple-darwin10-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.9)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc --version
gcc (GCC) 4.6.0
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ valgrind --version
valgrind-3.6.0
Localhost JL: uname -a
Darwin localhost 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386
$ otool -L /usr/lib/libSystem.B.dylib
/usr/lib/libSystem.B.dylib:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
/usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 315.0.0)
When run with -v --gen-suppressions=yes, valgrind reports a lot more information, but there are still no suppressed errors.
This error appears resolved in latest Valgrind SVN source. A number of internal bugs in Valgrind have been resolved, as well as known Apple system library bugs suppressed.
Note this is running on OS X 10.10.4
$ ./vg-in-place ../../test
==55558== Memcheck, a memory error detector
==55558== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==55558== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==55558== Command: ../../test
==55558==
--55558-- ../../test:
--55558-- dSYM directory is missing; consider using --dsymutil=yes
AUTHORS
COPYING
COPYING.DOCS
Makefile
...
vg-in-place
xfree-3.supp
xfree-4.supp
==55558==
==55558== HEAP SUMMARY:
==55558== in use at exit: 39,331 bytes in 419 blocks
==55558== total heap usage: 523 allocs, 104 frees, 68,971 bytes allocated
==55558==
==55558== LEAK SUMMARY:
==55558== definitely lost: 0 bytes in 0 blocks
==55558== indirectly lost: 0 bytes in 0 blocks
==55558== possibly lost: 0 bytes in 0 blocks
==55558== still reachable: 0 bytes in 0 blocks
==55558== suppressed: 39,331 bytes in 419 blocks
==55558==
==55558== For counts of detected and suppressed errors, rerun with: -v
==55558== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ ./vg-in-place --version
valgrind-3.11.0.SVN