Monday, 21 December 2015

Finding memory over-usage

Memory leaks are a common problem when writing software - this is where the software has asked the operating system (OS) for a lump of memory, but has forgotten to tell the OS when it finishes using that memory.

Tracking down memory leaks can be a real pain, but software such as Valgrind Memcheck helps - Valgrind lets you run the software (very very slowly!) and keeps track of when memory is allocated and freed.  When the software exits, Valgrind gives you a summary of memory that still hasn't been freed.

However, there is another problem very similar to a memory leak - if the memory has been allocated, but is kept in use by your software for far longer than necessary.  Eventually the software will release the memory again, so technically this isn't a "leak", but the effect is very similar.  Since the software is holding onto memory allocations for a long time, it may require a lot more of the computer's memory than you would expect.  On shut down, the software would usually release all of these memory allocations, so the usual method of tracking down leaks (i.e. see what hasn't been released at the end) isn't going to work.

But we can still use Valgrind, and rather than wait until the program exits we can get a list of currently allocated memory at any point while the program is running.  Obviously this includes everything that has been allocated, not just the "problem" allocations.  However, if the problem allocations amount to a very significant amount of memory, this tends to stick out like a sore thumb.

First of all run the program to be debugged inside Valgrind with the --vgdb=full commandline argument:
valgrind --vgdb=full --track-fds=yes --tool=memcheck --leak-check=full --show-reachable=yes --leak-resolution=high --num-callers=40 ./some_executable

In another window, we can then fire up the the gdb debugger:
gdb some_executable
At the gdb prompt, the following will connect to the running process and obtain the list of allocations:
target remote | vgdb
set logging file /tmp/allocations.txt
set logging on
monitor leak_check full reachable any
The memory allocations will be logged to /tmp/allocations.txt.  You can do this several times while the program is running and then compare the outputs. 

[Edit:  You can use vgdb directly, instead of gdb: "vgdb leak_check full reachable any"]

No comments:

Post a comment