How to run valgrind with basic c example? - c++

Installation:
bzip2 -d valgrind-3.10.1.tar.bz2
tar -xf valgrind-3.10.1.tar
then:
./configure
make
make install
or simplier
sudo apt-get install valgrind
How to run valgrind on that simple program example1.c
#include <stdlib.h>
int main()
{
char *x = malloc(100); /* or, in C++, "char *x = new char[100] */
return 0;
}
Run:
valgrind --tool=memcheck --leak-check=yes example1
valgrind: example1: command not found
Output from console:
valgrind: example1: command not found

It looks good. You only need to add a ./ before your executable. Without it, valgrind fails to find it and reports 'command not found'.
valgrind --tool=memcheck --leak-check=yes ./example1
^

First, compile your C program (-g is extremely important; without debug info in the executable valgrind cannot tell you line numbers from the source code where the violations occur nor the original line of the allocations of the memory being violated.):
gcc -g example1.c -o example1
Then run valgrind on the executable:
valgrind --tool=memcheck --leak-check=yes ./example1

Related

How can I enable coredump in macos

The following code can cause core dump
#include <cstdio>
int main(){
printf("%d", *((int*)1));
}
However when I run on my mac, there is no coredump generated in /cores
calvin#CalvinPC test % ./a
zsh: segmentation fault ./a
calvin#CalvinPC test % ls -a /cores
. ..
However, I already have ulimit -c unlimited, and sudo sysctl kern.coredump=1
So, how can I cause a core dump in macos?

Using Valgrind on files made with make

I'm trying to use valgrind on a program which is the output of the make command using this makefile:
# Intlist makefile
P = intlist
C = g++
F = -m32 -g -O0 -Wall
O = IntListTest.o IntList.o
$(P): $(O)
$(C) $(F) -o $(P) $(O)
IntListTest.o: IntListTest.cpp IntList.h
$(C) $(F) -c IntListTest.cpp
IntList.o: IntList.cpp IntList.h
$(C) $(F) -c IntList.cpp
clean:
rm $(P) $(O)
When I run valgrind on intlist, it generates this:
==130929== Memcheck, a memory error detector
==130929== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==130929== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==130929== Command: intlist
==130929==
valgrind: Fatal error at startup: a function redirection
valgrind: which is mandatory for this platform-tool combination
valgrind: cannot be set up. Details of the redirection are:
valgrind:
valgrind: A must-be-redirected function
valgrind: whose name matches the pattern: strlen
valgrind: in an object with soname matching: ld-linux.so.2
valgrind: was not found whilst processing
valgrind: symbols from the object with soname: ld-linux.so.2
valgrind:
valgrind: Possible fixes: (1, short term): install glibc's debuginfo
valgrind: package on this machine. (2, longer term): ask the packagers
valgrind: for your Linux distribution to please in future ship a non-
valgrind: stripped ld.so (or whatever the dynamic linker .so is called)
valgrind: that exports the above-named function using the standard
valgrind: calling conventions for this platform. The package you need
valgrind: to install for fix (1) is called
valgrind:
valgrind: On Debian, Ubuntu: libc6-dbg
valgrind: On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfo
valgrind:
valgrind: Note that if you are debugging a 32 bit process on a
valgrind: 64 bit system, you will need a corresponding 32 bit debuginfo
valgrind: package (e.g. libc6-dbg:i386).
valgrind:
valgrind: Cannot continue -- exiting now. Sorry.
I feel like there's something wrong with my makefile, but I'm not sure what it is. Any ideas are greatly appreciated. However, This takes place on a college-owned server where I don't have permission to install anything, so that isn't a solution in my case.
You are building a 32bit executable (the -m32 option in your compile/link lines) but from the output valgrind provides, you don't have all the support libraries available to run valgrind on a 32bit executable.
Do you really need your program to be 32bit? If not the simplest thing to do is remove the -m32 option and clean and rebuild everything.
If you really have to have a 32bit binary then read the output valgrind provides above carefully to determine what extra 32bit libraries you're missing and need to install.

Strange behavior with gdb printf

I have a issue with gdb printf in version 9.1
echo -e '#include<stdio.h> \n int main(){ \n printf("Hello"); \n }' > test.c
gcc -g test.c -o test
echo 'break test.c:4' > test.gdb
echo 'run' >> test.gdb
echo 'set $aux = (char*)malloc(256)' >> test.gdb
echo 'set $e = strcpy($aux, "abc")' >> test.gdb
echo 'printf "%s", $aux' >> test.gdb
gdb --batch --command=test.gdb test
Output with gdb 9.1:
Breakpoint 1 at 0x1167: file test.c, line 4.
Breakpoint 1, main () at test.c:4
4 }
�e���
Expected output (same as gdb v8):
Breakpoint 1 at 0x1167: file test.c, line 4.
Breakpoint 1, main () at test.c:4
4 }
abc
I've checked charset, but it seems ok.
Any idea about that?
This is Bug 25650 - GDB can't 'printf' a convenience variable holding an inferior address, fixed in gdb 9.2.
If you can't upgrade to gdb 9.2 but can recompile your existing distro's gdb 9.1, there is a two-line patch.
On Ubuntu 20.04, which comes with gdb 9.1-0ubuntu1:
run apt build-dep gdb to haul in the packages needed to build gdb from source
run apt install dpkg-dev (to get /usr/bin/dpkg-source)
uncomment the deb-src lines in /etc/apt/sources.list
run apt update
cd to an empty directory and run apt source gdb . Doing this in a fresh new directory will make it easier to clean things up after the compilation.
cd to gdb-9.1 and apply the patch to gdb/printcmd.c
build and install gdb. For example, to put it in /usr/local/bin, the default, you'd run
mkdir build
cd build
../configure
make
make install

"sh: ./<file> not found" error when trying to execute a file

I've come across a weirdest problem I ever met. I'm cross-compiling an app for ARM CPU with Linux on-board. I'm using buildroot, and all goes well until I'm trying to run the application on the target: I'm getting -sh: ./hw: not found. E.g.:
$ cat /tmp/test.cpp
#include <cstdio>
#include <vector>
int main(int argc, char** argv){
printf("Hello Kitty!\n");
return 0;
}
$ ./arm-linux-g++ -march=armv7-a /tmp/test.cpp -o /tftpboot/hw
load the executable to the target; then issuing on the target:
# ./hw
-sh: ./hw: Permission denied
# chmod +x ./hw
# ./hw
-sh: ./hw: not found
# ls -l ./hw
-rwxr-xr-x 1 root root 6103 Jan 1 03:40 ./hw
There's more to it: upon building with distro compiler, like arm-linux-gnueabi-g++ -march=armv7-a /tmp/test.cpp -o /tftpboot/hw, the app runs fine!
I compared executables through readelf -a -W /tftpboot/hw, but didn't notice much defference. I pasted both outputs here. The only thing I noticed, are lines Version5 EABI, soft-float ABI vs Version5 EABI. I tried removing the difference by passing either of -mfloat-abi=softfp and -mfloat-abi=soft, but compiler seems to ignore it. I suppose though, this doesn't really matter, as compiler doesn't even warn.
I also thought, perhaps sh outputs this error if an executable is incompatible in some way. But on my host PC I see another error in this case, e.g.:
$ sh /tftpboot/hw
/tftpboot/hw: 1: /tftpboot/hw: Syntax error: word unexpected (expecting ")")
sh prints this weird error because it is trying to run your program as a shell script!
Your error ./hw: not found is probably caused by the dynamic linker (AKA ELF interpreter) not being found. Try compiling it as a static program with -static or running it with your dynamic loader: # /lib/ld-linux.so.2 ./hw or something like that.
If the problem is that the dynamic loader is named differently in your tool-chain and in your runtime environment you can fix it:
In the runtime environment: with a symbolic link.
In the tool-chain: use -Wl,--dynamic-linker=/lib/ld-linux.so.2

running valgrind

I have not used valgrind before, but I need to use it to check memory leak. I ran the following command:
G_SLICE=always-malloc G_DEBUG=gc-friendly valgrind -v --tool=memcheck --leak-check=full --num-callers=40 --log-file=valgrind.log example1
valgrind: example1: command not found
I followed instructions from this site:
http://www.cprogramming.com/debugging/valgrind.html
this is what the example1 file looks like:
#include <stdlib.h>
int main()
{
char *x = malloc(100); /* or, in C++, "char *x = new char[100] */
return 0;
}
I know valgrind is installed on my machine, regardless I ran the following command to make sure:
sudo apt-get install valgrind
Can somebody pls. guide me how to get valgrind working....thx!
You forgot to give it the path to the program you wanted to run! Replace example1 with the path to the executable.
For example:
G_SLICE=always-malloc G_DEBUG=gc-friendly valgrind -v \
--tool=memcheck --leak-check=full --num-callers=40 \
--log-file=valgrind.log ./example1