Reading output from valgrind

Hello. I am writing a Monte Carlo simulation engine, and I am experiencing what I believe to be memory leaks in my software. For example, I am running a certain calculation, and it turns out that unless I have a

std::cout <<"Some string" << std::endl;

in the region where the computation is written, my code does not work.

There must be an error/memory leak in my program if I am seeing such behavior. So, I decided to run valgrind. This how I compiled it all:
g++ ·-std=c++14·-Wall·-Wextra·-Wdisabled-optimization·-Werror·-pedantic·-Ofast·-march=native·-fopenmp·-g main.cpp misc.cpp classes.cpp -o cosolv_ani
Then I ran it as:
valgrind --leak-check=full --show-leak-kinds=all -s --log-file=valgrind.out ./cosolv_ani -f 1 -M 1 -p 4mer.txt -t geom_and_esurf.txt -u energydump.mc -e orientation.mc -s stats.mc -o coords.mc

The output is quite large. Here is the link to it: https://pastebin.mozilla.org/tcfR5b8x.

My question is, how do I even start reading valgrind? What do these terms mean? I see references to main.cpp, misc.cpp, but I do not understand how to go about this problem...

I apologize for the wall of text, but how does one go about parsing through all of this information?
Last edited on
A memory leak does not cause a program to misbehave. All it does is to use up unnecessary amounts of memory. If you run out of memory it normally leads to slowdown or crash.

This is not much of a memory leak. I don't know if it's a true leak or not but it's not what causing your problems.

==992550== LEAK SUMMARY:
==992550== definitely lost: 64 bytes in 1 blocks
==992550== indirectly lost: 0 bytes in 0 blocks
==992550== possibly lost: 0 bytes in 0 blocks
==992550== still reachable: 73,000 bytes in 15 blocks
==992550== suppressed: 0 bytes in 0 blocks

I usually use valgrind with default settings so I'm not sure if any of the flags you used disables other checks but I would look more for messages such as "Invalid read of size 8". I don't see anything like that in your output though.

If valgrind doesn't help you might want to try a UB/memory sanitizer. Modern compilers often come with these.
g++ -fsanitize=undefined,address ...
https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html

Note that -Ofast enables some optimizations that can affect the outcome of calculations with floating-point numbers.
Last edited on
You seem to have a hell of a lot of options there. However your paste has expired, so we can no longer see your output (which must be considerable).
> std::cout <<"Some string" << std::endl;
> in the region where the computation is written, my code does not work.
Then you have an actual bug (a fairly nasty one).
Adding a cout like that should not cause a change of behaviour in the rest of the program.

TBH, you need to take that line out and try to find the problem(s).
Not leave it in and cross your fingers.

You also need to define "does not work".
- fails completely - ie crashes
- just produces the wrong answers.


> but how does one go about parsing through all of this information?
Start at the top and work your way down.

This is your first problem.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vex amd64->IR: unhandled instruction bytes: 0x62 0xF1 0xFD 0x8 0x6F 0x55 0x0 0x62 0xF1 0xFD
vex amd64->IR: REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR: VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=NONE
vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0
==992550== valgrind: Unrecognised instruction at address 0x40834e.
...
==992550== Either way, Valgrind will now raise a SIGILL signal which will
==992550== probably kill your program.
==992550==
==992550== Process terminating with default action of signal 4 (SIGILL)
==992550== Illegal opcode at address 0x40834E
==992550== at 0x40834E: construct<std::pair<int const, std::array<double, 3> >, const std::pair<int const, std::array<double, 3> >&> (new:169)
...
==992550== by 0x40834E: _M_insert_unique<const std::pair<int const, std::array<double, 3> >*> (stl_tree.h:2475)
==992550== by 0x40834E: map (stl_map.h:230)
==992550== by 0x40834E: __static_initialization_and_destruction_0(int, int) [clone .constprop.1147] (misc.cpp:40)
==992550== by 0x4473EC: __libc_csu_init (in /scratch/gpfs/satyend/MC_POLYMER/polymer_lattice/lattice_md/current/Explicit_Solvation/src/vanilla_hamiltonian/appropriately_biased_cosolvent/src/serial/cosolv_ani)
==992550== by 0x5E33C7D: (below main) (in /usr/lib64/libc-2.28.so)


It's still in the phase of initialising your global objects (that's the static_initialization_and_destruction part). It hasn't reached the beginning of main() yet.

That it died due to illegal instructions is a problem. Mostly you would see this by trying to call via an uninitialised function pointer. But the stack trace to the SIGILL is deep inside the ctor for STL map.

I would definitely take '-march=native' out of the compilation command line, because of this.
> ==992550== 2. The instruction is legitimate but Valgrind doesn't handle it,

Then try a valgrind again, to see if the program runs to completion and produces the output you expect, in addition to the valgrind report.


NB for later readers.
https://pastebin.mozilla.org/tcfR5b8x Expires in: 17 hours, 12 minutes
So if you're reading this after today (22/09/2022), the link is likely dead.

@mencecpp,
First things first: why don't you let us see your code? The three source files (main.cpp, misc.cpp, classes.cpp) plus any header files and any input files (or run-time input).

You have the -g flag set in your compile command: so why don't you just use the gdb debugger? Looking at the valgrind errors it seems more than likely that gdb will pick them up more readily, and gdb is (a little bit) kinder on the user than valgrind.

Obviously, tackle the first error first - it tends to cause an avalanche of other errors.

Since (from your compile command) you appear to be using openmp you might want to comment those lines out whilst you sort out the rest.

Simply adding an output line to make your program run is a red herring. It just tells you that you have an undiscovered error prior to it.
lastchance wrote:
You have the -g flag set in your compile command: so why don't you just use the gdb debugger? Looking at the valgrind errors it seems more than likely that gdb will pick them up more readily, and gdb is (a little bit) kinder on the user than valgrind.

The -g flag also helps improve Valgrind's output.

Valgrind is great for finding many memory related problems (invalid reads and writes, use of uninitialized values, etc.)
https://valgrind.org/docs/manual/mc-manual.html#mc-manual.overview

When having a program crash my experience is that gdb tells me where the crash happened while valgrind often tells me what caused the crash. These two are not always close together in the code.


Valgrind wrote:
Compile your program with -g to include debugging information so that Memcheck's error messages include exact line numbers. Using -O0 is also a good idea, if you can tolerate the slowdown. With -O1 line numbers in error messages can be inaccurate, although generally speaking running Memcheck on code compiled at -O1 works fairly well, and the speed improvement compared to running -O0 is quite significant. Use of -O2 and above is not recommended as Memcheck occasionally reports uninitialised-value errors which don't really exist.
https://valgrind.org/docs/manual/quick-start.html
Last edited on
Topic archived. No new replies allowed.