Sometimes the unfortunate situation appears when a program begins to store memory for no obvious reason. The effect is usually noticed only after all of the computer’s memory fills up, and the system becomes unstable. The situation occurs when a programmer forgets to release dynamic memory for variables in the program. Sometimes, the working context can be quite complicated, and the number of dynamically allocated variables can make it difficult to detect these leaks. To prevent such accidents, specialized analysis programs are used. Such a program is also worthwhile.
Valgrind is a suite of utility programs that can be used to troubleshoot memory usage, memory leakage detection, and profiling.
Valgrind is basically a virtual car. When executing a program using Valgrind, it is run in that virtual machine. On this occasion, certain code processing techniques and procedures are used to detect some types of programming errors. Valgrind runs only on Linux platforms. There are similar programs for Windows users, but they are usually commercial. Among the alternatives available on Windows systems, we can list: IBM Purify, Parasoft Insure ++, etc.
What are the categories of errors that Valgrind can detect?
Valgrind consists of a suite of utility programs. Probably the most used of them is memcheck, designed to analyze memory usage.
It can detect errors such as:
1. Using non-initialized memory
2. Accessing unallocated memory
3. Buffer overflows for buffered buffers
4. Some instances of incorrect memory access on the current stack
5. Memory leaks
6. Incorrect use of memory allocation/unallocation functions
Besides memcheck, there are also:
a. Callgrind -> useful for generating callgraphs (for profiling)
b. Cachegrind -> useful for profiling on cache usage
c. Massif -> Useful for profiling on using memory allocated dynamically
d. Helgrind -> Detects Typical Mistakes in Using POSIX Threads
On Debian (or Debian-derived systems such as Ubuntu), it can be installed by running:
sudo apt-get install valgrind
Valgrind does not require the code of a program to be adjusted, but uses the executable (binary) associated with a program directly. On a regular run, Valgrind will get the argument – tool to specify the utility used and the program that will be checked for memory errors. Valgrind is a basic utility in debugging programs. It’s easy to use (it’s not intrusive, it does not need to change sources) and it detects a large number of programming errors that result from faulty memory management.
We will give an example of the use of valgrind on accessing memory unlabeled:
We have the following source code (deallocated_memory_access.c):
#include <stdlib.h>
int main ()
{
int * p = (int *) malloc (sizeof (int));
* p = 1;
free (p);
/ * bug – access to deallocated memory pointed by p * /
* p = 2;
return EXIT_SUCCESS;
In this program, unlocked memory is accessed at the following line: * p = 2.
Compilation:
gcc -Wall -Wextra -g -O0 deallocated_memory_access.c -o deallocated_memory_access
Executing using memcheck:
Code: Select all
valgrind –tool = memcheck –leak-check = yes ./deallocated_memory_access
we get:
== 11741 == Invalid write of size 4
== 11741 == at 0x804842B: main (deallocated_memory_access.c: 9)
== 11741 == The address 0x41b1028 is 0 bytes inside a block of size 4 free’d
== 11741 == at 0x4025DFA: free (vg_replace_malloc.c: 323)
== 11741 == by 0x8048427: main (deallocated_memory_access.c: 7)
The message offered by Valgrind tells us the following:
– Invalid memory access was written in write, 4 bytes (int type, on my system)
– access was made to line 9 in the file of allocated_memory_access.c
– The address where writing was attempted was 0x41b1028. This address is located in a dynamically allocated 4-byte memory block (again equal to the int on my system) but has previously been unallocated at line 7 in the file deallocated_memory_access.c