running valgrind - c++

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

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.

Different behavior when I running a program compiled with G ++ in Docker

The behavior of the executable is different if it is run inside the docker, or on the host. But this only happens when we change the optimization level of G++.
Compiler:
g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
I am trying to execute the following code:
#include <cstdio>
#include <cstring>
int main()
{
int nOrd =3395;
char cOrd[] = "003395";
char cAux2[256];
strcpy(cAux2, cOrd);
int nRest = nOrd % 26;
printf("BEFORE SPRINTF %s\n\n\n", cAux2);
sprintf(cAux2, "%s%c", cAux2, (nRest+65));
printf("AFTER SPRINTF %s\n\n\n", cAux2);
return 0;
}
If I compile with:
g++ -o FastCompile FastCompile.c -DNDEBUG -Os
And I run in the host. The output is as expected:
BEFORE SPRINTF 003395
AFTER SPRINTF 003395P
If I create an image with this executable and run inside the docker, I have:
Docker version 18.09.4, build d14af54266
Dockerfile:
FROM debian
RUN apt-get update && apt-get install -y \
libssl-dev
COPY fast/ /usr/local/
ENTRYPOINT ["usr/local/FastCompile"]
$docker build -t fastcompile .
$docker run fastcompile
BEFORE SPRINTF 003395
AFTER SPRINTF P
If I remove the -Os and re-compile with:
g++ -o FastCompile FastCompile.c -DNDEBUG
The behavior is correct inside the Docker.
So,
Is it a Docker problem? Or is it expected behavior?
Your code has undefined behavior.
sprintf(cAux2, "%s%c", cAux2, (nRest+65));
reads from and writes to the same object. To fix it you can use cOrd in the call so you are not reading from your buffer. That would look like
sprintf(cAux2, "%s%c", cOrd, (nRest+65));
Also note that (nRest+65) gives you a int, not a char as you format specifier states it should be. That is also undefined behavior. You need to cast it to a char to fix it like
sprintf(cAux2, "%s%c", cOrd, char(nRest+65));

How to run valgrind with basic c example?

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

"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