Ubuntu System Monitor and Valgrind to Discover Memory Leaks in C++ Applications

Ubuntu System Monitor and valgrind to discover memory leaks in C++ applications

Another tool you can try is the /lib/libmemusage.so library:

$ LD_PRELOAD=/lib/libmemusage.so vim 

Memory usage summary: heap total: 4643025, heap peak: 997580, stack peak: 26160
total calls total memory failed calls
malloc| 42346 4528378 0
realloc| 52 7988 0 (nomove:26, dec:0, free:0)
calloc| 34 106659 0
free| 28622 3720100
Histogram for block sizes:
0-15 14226 33% ==================================================
16-31 8618 20% ==============================
32-47 1433 3% =====
48-63 4174 9% ==============
64-79 4736 11% ================
80-95 313 <1% =
...

(I quit vim immediately after startup.)

Maybe the histogram of block sizes will give you enough information to tell where leaks may be happening.

valgrind is very configurable; --leak-check=full --show-reachable=yes might be a good starting point, if you haven't tried it yet.


"Virtual Memory", "Resident Memory", "Writable Memory" and "Memory"

Virtual memory is the address space that your application has allocated. If you run malloc(1024*1024*100);, the malloc(3) library function will request 100 megabytes of storage from the operating system (or handle it out of the free lists). The 100 megabytes will be allocated with mmap(..., MAP_ANONYMOUS), which won't actually allocate any memory. (See the rant at the end of the malloc(3) page for details.) The OS will provide memory the first time each page is written.

Virtual memory accounts for all the libraries and executable objects that are mapped into your process, as well as your stack space.

Resident memory is the amount of memory that is actually in RAM. You might link against the entire 1.5 megabyte C library, but only use the 100k (wild guess) of the library required to support the Standard IO interface. The rest of the library will be demand paged in from disk when it is needed. Or, if your system is under memory pressure and some less-recently-used data is paged out to swap, it will no longer count against Resident memory.

Writable memory is the amount of address space that your process has allocated with write privileges. (Check the output of pmap(1) command: pmap $$ for the shell, for example, to see which pages are mapped to which files, anonymous space, the stack, and the privileges on those pages.) This is a reasonable indication of how much swap space the program might require in a worst-case swapping scenario, when everything must be paged to disk, or how much memory the process is using for itself.

Because there are probably 50--100 processes on your system at a time, and almost all of them are linked against the standard C library, all the processes get to share the read-only memory mappings for the library. (They also get to share all the copy-on-write private writable mappings for any files opened with mmap(..., MAP_PRIVATE|PROT_WRITE), until the process writes to the memory.) The top(1) tool will report the amount of memory that can be shared among processes in the SHR column. (Note that the memory might not be shared, but some of it (libc) definitely is shared.)

Memory is very vague. I don't know what it means.

How I can detect memory leaks of C++ application in Linux (Ubuntu OS)?

Check out Valgrind, it should be in the Ubuntu repository. it can give you detailed information about memory usage in C++ programs. Kind of like a debugger for memory usage.

valgrind --tool=memcheck <your_app> <your_apps_params>

Can using Valgrind on Linux also help when the app is compiled on Solaris?

Generally speaking, if the code execution path is the same on both systems and you clean up the memory leaks on one then yes, it will clean them up on the other system too.

It's not quite so straight forward when things differ between the machines though. EG, it tries to do one thing on the linux system and another thing on the solaris system.

Valgrind is a great tool and the best thing to do is try it on linux and see if it cleans up the leaks on solaris too (check with ps or another tool that lists the memory size under solaris and make sure it doesn't increase there).

How to find memory leak in a C++ code/project?

Instructions

Things You'll Need

  • Proficiency in C++
  • C++ compiler
  • Debugger and other investigative software tools

1

Understand the operator basics. The C++ operator new allocates heap memory. The delete operator frees heap memory. For every new, you should use a delete so that you free the same memory you allocated:

char* str = new char [30]; // Allocate 30 bytes to house a string.

delete [] str; // Clear those 30 bytes and make str point nowhere.

2

Reallocate memory only if you've deleted. In the code below, str acquires a new address with the second allocation. The first address is lost irretrievably, and so are the 30 bytes that it pointed to. Now they're impossible to free, and you have a memory leak:

char* str = new char [30]; // Give str a memory address.

// delete [] str; // Remove the first comment marking in this line to correct.

str = new char [60]; /* Give str another memory address with
the first one gone forever.*/

delete [] str; // This deletes the 60 bytes, not just the first 30.

3

Watch those pointer assignments. Every dynamic variable (allocated memory on the heap) needs to be associated with a pointer. When a dynamic variable becomes disassociated from its pointer(s), it becomes impossible to erase. Again, this results in a memory leak:

char* str1 = new char [30];

char* str2 = new char [40];

strcpy(str1, "Memory leak");

str2 = str1; // Bad! Now the 40 bytes are impossible to free.

delete [] str2; // This deletes the 30 bytes.

delete [] str1; // Possible access violation. What a disaster!

4

Be careful with local pointers. A pointer you declare in a function is allocated on the stack, but the dynamic variable it points to is allocated on the heap. If you don't delete it, it will persist after the program exits from the function:

void Leak(int x){

char* p = new char [x];

// delete [] p; // Remove the first comment marking to correct.

}

5

Pay attention to the square braces after "delete." Use delete by itself to free a single object. Use delete [] with square brackets to free a heap array. Don't do something like this:

char* one = new char;

delete [] one; // Wrong

char* many = new char [30];

delete many; // Wrong!

6

If the leak yet allowed - I'm usually seeking it with deleaker (check it here: http://deleaker.com).

Valgrind on ARMv5

Valgrind is a very powerful tool and it's pretty sad that it does not work on ARMv5 because it makes debugging memory leaks and invalid memory accesses more difficult on this platform.

I see several less powerful options. You can try to enable some additional checks within the C library by setting the MALLOC_CHECK_ environment variable. If your compiler is GCC 4.8 or higher you can try AddressSanitizer (I never used it on ARMv5 though).

Memory leak detectors for C?

second the valgrind... and I'll add electric fence.

Analysing resource leaks in network applications (socket handlers etc)

Valgrind has the ability to track a few of the resources you are interested in:

  • Memory via memcheck

  • File descriptors via the --track-fds=yes memcheck option

  • Threads and locks via Helgrind and DRD

The generated information is not always detailed, but it can be quite helpful.



Related Topics



Leave a reply



Submit