Why does valgrind point to a memory leak at libc-start.c? - memory-leaks

After building an app, it keeps crashing due to some memory leak. The beginning of the valgrind report reads:
==70588==
==70588== HEAP SUMMARY:
==70588== in use at exit: 215,842 bytes in 2,327 blocks
==70588== total heap usage: 77,289 allocs, 74,962 frees, 7,513,045 bytes allocated
==70588==
==70588== 20 bytes in 1 blocks are definitely lost in loss record 182 of 510
==70588== at 0x4849D8C: malloc (in /usr/lib/aarch64-linux-gnu/valgrid/vgpreload_memcheck-arm64-linux.so
==70588== by 0x15481F: ??? (in /usr/bin/tcsh)
==70588== by 0x15C313: ??? (in /usr/bin/tcsh)
==70588== by 0x117EAB: ??? (in /usr/bin/tcsh)
==70588== by 0x492C08F: (below main) (libc-start.c:308)
A similar message is repeated for several records but the strange thing is that it always points to libc-start.c, which doesn't provide much insight into which piece of the app is causing the memory leak (the app itself has tens of thousands of lines with a mix of C/Fortran and many internal dependencies). Any suggestions on what might be the root of the problem or what to look at would be welcomed.

Related

Memory leakage :Definitely lost and possibly lost

When i am running valgrind by adding a leakage to my code,I am getting leakage as still reachable for first allocation of block and then showing as definitely lost for 9 blocks.Possibly lost is showing due to other portion of the code. Why is this so ?
main()
{
........
char *ptr;
For(i=0;i<10;i++)
{
ptr=malloc(sizeof * ptr);
}
.....
}
Report:
HEAP SUMMARY:
==13832== in use at exit: 202,328 bytes in 62 blocks
==13832== total heap usage: 332 allocs, 270 frees, 283,928 bytes allocated
==13832==
==13832== LEAK SUMMARY:
==13832== definitely lost: 90 bytes in 9 blocks
==13832== indirectly lost: 0 bytes in 0 blocks
==13832== possibly lost: 202,180 bytes in 49 blocks
==13832== still reachable: 58 bytes in 4 blocks
==13832== suppressed: 0 bytes in 0 blocks
==13832== Rerun with --leak-check=full to see details of leaked memory
Adding to Florian's answer, here are a few examples of where you would have interior pointers
A memory manager. For instance, you know that you are going to be allocating very many small blocks of memory of the same size, so you write a memory manager that allocates large blocks and the subdivides them into your small size. These sub-block allocations are interior pointers.
A memory debugger. In this case, you allocate more memory than requested, and the extra memory is used to pad the allocated memory. The pointer returned to the client is an interior pointer.
Data structures such as Pascal strings. Here you allocate memory for the string and its size. The size comes before the string so the pointer to the start of the string is an interior pointer.
The memcheck manual says this:
"Possibly lost". […] This means that a chain of one or more pointers to the block has been found, but at least one of the pointers is an interior-pointer. This could just be a random value in memory that happens to point into a block, and so you shouldn't consider this ok unless you know you have interior-pointers.
So this should normally happen only if you have nested data structures on the heap where pointers point into an allocation, at an offset, and not directly at the beginning.

Valgrind possibly lost memory

When running valgrind with --leak-check=full the generated reports include information about memory "possibly lost".
There is some information on this in the valgrind manual, as well as some example reports.
http://valgrind.org/docs/manual/mc-manual.html
LEAK SUMMARY:
definitely lost: 4 bytes in 1 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 95 bytes in 6 blocks
of which reachable via heuristic:
stdstring : 56 bytes in 2 blocks
length64 : 16 bytes in 1 blocks
newarray : 7 bytes in 1 blocks
multipleinheritance: 8 bytes in 1 blocks
suppressed: 0 bytes in 0 blocks
In my own system, i get plenty of "possibly" lost memory when executing my multi-threaded test binary with valgrind.
What exactly does it mean that valgrind reports memory as "possibly lost"? Was it lost or wasn't it in this particular execution. Memory leakage should be more black and white than "possibly lost" in my opinion.
Roughly the categories are
Still in use = there is a live pointer to the memory at exit
Definitely lost = there are no live pointers to the memory
Indirectly lost = there are pointers to the memory but the pointers themselves are in "definitely lost" memory.
Possibly lost = there is a pointer but not the start of the memory.
The main reasons that Valgrind will detect possibly lost are either
Some junk pointer that accidentally points into the block. You should consider this as a definite loss.
A memory manager that allocates sub-blocks or guard bands.
So as a rule, if you are not using a memory manager, consider your possible losses as definite ones.

Decoding output from Valgrind

I'm trying to understand the output from Valgrind having executed it as follows:
valgrind --leak-check=yes "someprogram"
The output is here:
==30347==
==30347== HEAP SUMMARY:
==30347== in use at exit: 126,188 bytes in 2,777 blocks
==30347== total heap usage: 4,562 allocs, 1,785 frees, 974,922 bytes
allocated
==30347==
==30347== LEAK SUMMARY:
==30347== definitely lost: 0 bytes in 0 blocks
==30347== indirectly lost: 0 bytes in 0 blocks
==30347== possibly lost: 0 bytes in 0 blocks
==30347== still reachable: 126,188 bytes in 2,777 blocks
==30347== suppressed: 0 bytes in 0 blocks
==30347== Reachable blocks (those to which a pointer was found) are
not shown.
==30347== To see them, rerun with: --leak-check=full --show-reachable=yes
==30347==
==30347== For counts of detected and suppressed errors, rerun with: -v
==30347== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
According to the output, there are no lost bytes, but there seems to be still reachable blocks. So do I have a memory leak?
No.
You are most concerned with unreachable blocks. What you are seeing here is that there are active variables that are still "pointing" at reachable blocks of memory. They are still in scope.
An unreachable block would be, for instance, memory that you have allocated dynamically, used for a period of time and then all of the references to it have gone out of scope even though the program is still executing. Since you no longer have any handles pointing to them they are now unrecoverable, creating a memory leak.
Here is a quote from the Valgrind docs:
"still reachable" means your program is probably ok -- it didn't free some memory it could have. This is quite common and often reasonable. Don't use --show-reachable=yes if you don't want to see these reports.

MPI memory leak

I am writing some code that uses MPI and I was keeping noticing some memory leaks when running it with valgrind. While trying to identify where the problem was, I ended up with this simple (and totally useless) main:
#include "/usr/include/mpi/mpi.h"
int main(int argc,char** argv)
{
MPI_Init(&argc, &argv);
MPI_Finalize();
return 0;
}
As you can see, this code doesn't do anything and shouldn't create any problem. However, when I run the code with valgrind (both in the serial and parallel case), I get the following summary:
==28271== HEAP SUMMARY:
==28271== in use at exit: 190,826 bytes in 2,745 blocks
==28271== total heap usage: 11,214 allocs, 8,469 frees, 16,487,977 bytes allocated
==28271==
==28271== LEAK SUMMARY:
==28271== definitely lost: 5,950 bytes in 55 blocks
==28271== indirectly lost: 3,562 bytes in 32 blocks
==28271== possibly lost: 0 bytes in 0 blocks
==28271== still reachable: 181,314 bytes in 2,658 blocks
==28271== suppressed: 0 bytes in 0 blocks
I don't understand why there are these leaks. Maybe it's just me not able to read the valgrind output or to use MPI initialization/finalization correctly...
I am using OMPI 1.4.1-3 under ubuntu on a 64 bit architecture, if this can help.
Thanks a lot for your time!
The OpenMPI FAQ addresses issues with valgrind. This refers initalization issues and memory leaks during finalization - which should have no practical negative impact.
There are many situations, where Open MPI purposefully does not
initialize and subsequently communicates memory, e.g., by calling
writev. Furthermore, several cases are known, where memory is not
properly freed upon MPI_Finalize.
This certainly does not help distinguishing real errors from false
positives. Valgrind provides functionality to suppress errors and
warnings from certain function contexts.
In an attempt to ease debugging using Valgrind, starting with v1.5,
Open MPI provides a so-called Valgrind-suppression file, that can be
passed on the command line:
mpirun -np 2 valgrind
--suppressions=$PREFIX/share/openmpi/openmpi-valgrind.supp
You're not doing anything wrong. Memcheck false positives with valgrind are common, the best you can do is suppress them.
This page of the manual speaks more about these false positives. A quote near the end:
The wrappers should reduce Memcheck's false-error rate on MPI
applications. Because the wrapping is done at the MPI interface, there
will still potentially be a large number of errors reported in the MPI
implementation below the interface. The best you can do is try to
suppress them.

help required regarding memory leak

my application is causing memory leak of 10mb when the first timeout occurs. Heare i am using linux timer functions (timer_create etc.,).
For the subsequent timeouts no issue is there. I doubt some problem with linux timers.
I debugged it with valgrind and purify. Even these tools are of no help to me. In both the tools, memory leaked is shown as few kb's. But my application is causing memory leak of 10mb for the first timeout.
If anybody faced this problem earlier, please help me.
To find out which bits of you code is causing the leak (if any), compile your code to include debug symbols (i.e. include -g flag if you're using gcc), then run your program via valgrind.
valgrind --leak-check=full ./your_program
The run will take a little longer than usual, but when your program ends, the output from valgrind should tell you how much memory you've leaked and where the cuplrits are.
Sample output:
==10934== HEAP SUMMARY:
==10934== in use at exit: 10 bytes in 10 blocks
==10934== total heap usage: 10 allocs, 0 frees, 10 bytes allocated
==10934==
==10934== 10 bytes in 10 blocks are definitely lost in loss record 1 of 1
==10934== at 0x4024F20: malloc (vg_replace_malloc.c:236)
==10934== by 0x8048402: main (a.c:8)
==10934==
==10934== LEAK SUMMARY:
==10934== definitely lost: 10 bytes in 10 blocks
==10934== indirectly lost: 0 bytes in 0 blocks
==10934== possibly lost: 0 bytes in 0 blocks
==10934== still reachable: 0 bytes in 0 blocks
==10934== suppressed: 0 bytes in 0 blocks
update
Since you're already using valgrind, perhaps you could try using the Massif tool that comes with it. It should be able to paint a more accurate picture of memory usage (compare to simply watching top).
Check out this tutorial to see how it can be used. You may need some additional options to get a sensible graph depending on the runtime and mem usage of your program. Some useful options are described a few pages later in the tutorial.
Good luck.

Resources