Lets take a look into how we use the tool 'memcheck' so that we detect , try and avoid the memory related issues in our program.
First of all we need to create a memory leak so that we have something to detect .
We write a program that consists of a memory leak . Here is one such in a file ' pgm.c'
1 #include <stdlib.h>
2 #include <string.h>
3 void f(char *s)
4 {
5 char *x = malloc(strlen(s));
6 x[7] = 0;
7 }
8 int main()
9 {
10 char *s="Hello";
11 f(s);
12 }
As you could see , there are two major memory related bugs in this code:
1) Trying to write in the location x[7] which is out of the allocated memory space .This will lead to what is called a 'heap block overrun' .
2) The memory that is allocated to x remains unused . This memory becomes garbage on returning from the function . In short , you have seen a 'memory leak '.
Now lets try and detect the two problems using memcheck :
You need to have valgrind installed in your system .
$ : apt-get install valgrind
if you don't have it already .
Do
$: cc -g pgm.c
We compile the program using the -g option so that the line number informations are displayed when using memcheck .
Do
$: valgrind --leak-check = yes a.out
the option ' --leak-check ' being set equal to yes displays the informations on memory leak issues .
Now lets look out what are the informations that are being displayed when the memcheck tool is used .
First lets have a look into the 'heap block overrun' problem :
==3350== Invalid write of size 1
==3350== at 0x80483F6: f (pgm.c:6)
==3350== by 0x804841D: main (pgm.c:11)
==3350== Address 0x419102f is 2 bytes after a block of size 5 alloc'd
==3350== at 0x4023D6E: malloc (vg_replace_malloc.c:207)
==3350== by 0x80483EC: f (pgm.c:5)
==3350== by 0x804841D: main (pgm.c:11)
The above few lines is the code that was generated by memcheck .
'3350' is the process id .
The actual error is seen right at the first line .
'Invalid write of size 1' .
You get a stack trace right after this line , that
the invalid write has occured at the 6th line as a result of the 12th line . You could see what line numbers '6' and '11' do by having a look into our code , its the point of occurence of the error and the function call respectively.
A line showing the the fact that the location you are trying to access ( x[7] ) is 2 bytes after the allocated area can also be seen added with lines that contain information about the main and the function .These lines provide great help to the programmer especially when the case becomes a lot more complicated .
Now the informations that are displayed about the 'memory leak problem' can also be looked into .
==3350== LEAK SUMMARY:
==3350== definitely lost: 5 bytes in 1 blocks.
==3350== possibly lost: 0 bytes in 0 blocks.
==3350== still reachable: 0 bytes in 0 blocks.
==3350== suppressed: 0 bytes in 0 blocks.
You could view the lines that provide information about the memory leak problem .
The first line of the 'LEAK SUMMARY ' is the most significant to us . It shows the amount of memory definitely lost ( 5 Bytes ). Changes need to be made in the program so that the memory leak is prevented .
Memcheck produces these result which helps the programmer so as to view and correct the memory related issues rather convincingly . It needs to be noted that Memcheck is a 'dynamic instrumentation tool ' and not a static tool like 'lint ' . Hence to detect the memory leaks in a program , the control actually needs to get transferred to that segment of the program where the issues occur . In short you need to invoke the function 'f' from your 'main' so that Memcheck could detect those memory related issues that exists within the function 'f' .
No comments:
Post a Comment