Finding Memory Leaks Using mtrace

mtrace is a nice GNU extension which is used to diagnose dynamic memory allocation in C/C++ programs. It can also be used for finding memory leaks. I am going to demonstrate a memory leak problem in a simple C++ program. Look at the following code:


// File: m-test.cpp

#include <iostream>
#include <cstdlib>

#define SIZE 16

using namespace std;

bool isPalindrome(char *);

int main()
{
  char *str;
  while(true)
  {
    str = (char *)malloc(SIZE);
    cout << "Enter string to check Palindrome or quit to exit: ";
    cin >> str;
    if(strcmp(str, "quit") == 0)
      break;
    if(isPalindrome(str))
      cout << str << " is a Palindrome." << endl;
    else
      cout << str << " is NOT a Palindrome." << endl;      
  }
  return 0;
}

bool isPalindrome(char *str)
{
  int str_len = strlen(str);
  for(int i = 0; i < str_len/2; i++)
    if(str[i] != str[str_len-i-1])
      return false;
  return true;
}

It is a simple C++ program which checks whether the input string is a palindrome or not. I compiled and ran using following commands and it exeucutes perfectly:


munir@ubuntu:~/prog/c$ g++ m-test.cpp -Wall -g -o m-test
munir@ubuntu:~/prog/c$ ./m-test
Enter string to check Palindrome or quit to exit: ababa
ababa is a Palindrome.
Enter string to check Palindrome or quit to exit: abb
abb is NOT a Palindrome.
Enter string to check Palindrome or quit to exit: quit
munir@ubuntu:~/prog/c$

But did you find any thing wrong by reading code?

There is something wrong with dynamic memory allocation by using malloc(). Note that malloc(SIZE) is called every time when the program takes input from command promt. Lets trace the memory allocation using mtrace by following easy steps:

1) Include mcheck.h header file.
2) Place mtrace() in the first line of main(). mtrace will start tracing memory from this point.
3) Place muntrace() in the end of main() to stop tracing.
4) At command promt type export MALLOC_TRACE=mtrace.log to save output in mtrace.log file.
5) Compile and run the program again.

It should execute exactly like before but this time it will create a new file mtrace.log. Now come to the fun part. Open the text from mtrace.log:


munir@ubuntu:~/prog/c$ ./m-test2
Enter string to check Palindrome or quit to exit: aba
aba is a Palindrome.
Enter string to check Palindrome or quit to exit: a
a is a Palindrome.
Enter string to check Palindrome or quit to exit: aa
aa is a Palindrome.
Enter string to check Palindrome or quit to exit: abb
abb is NOT a Palindrome.
Enter string to check Palindrome or quit to exit: anm
anm is NOT a Palindrome.
Enter string to check Palindrome or quit to exit: quit

munir@ubuntu:~/prog/c$ cat mtrace.log
= Start
@ ./m-test2:(__gxx_personality_v0+0x161)[0x80488e5] + 0x804a378 0x10
@ ./m-test2:(__gxx_personality_v0+0x161)[0x80488e5] + 0x804a390 0x10
@ ./m-test2:(__gxx_personality_v0+0x161)[0x80488e5] + 0x804a3a8 0x10
@ ./m-test2:(__gxx_personality_v0+0x161)[0x80488e5] + 0x804a3c0 0x10
@ ./m-test2:(__gxx_personality_v0+0x161)[0x80488e5] + 0x804a3d8 0x10
@ ./m-test2:(__gxx_personality_v0+0x161)[0x80488e5] + 0x804a3f0 0x10
= End
munir@ubuntu:~/prog/c$


This is not in very readable form but what I understood from this result is that my program was allocated 0x10 bytes(16 bytes in decimal) of memory 6 times because malloc() was called 6 times.

Since the content of the log file is not very clear to understand therefore I am going to use a useful Perl script to interpret the results. This script is also called mtrace and its syntax is very simple to use: mtrace program log-file


munir@ubuntu:~/prog/c$ mtrace m-test2 mtrace.log

Memory not freed:
-----------------
   Address     Size     Caller
0x0804a378     0x10  at /home/munir/prog/c/m-test2.cpp:17
0x0804a390     0x10  at /home/munir/prog/c/m-test2.cpp:17
0x0804a3a8     0x10  at /home/munir/prog/c/m-test2.cpp:17
0x0804a3c0     0x10  at /home/munir/prog/c/m-test2.cpp:17
0x0804a3d8     0x10  at /home/munir/prog/c/m-test2.cpp:17
0x0804a3f0     0x10  at /home/munir/prog/c/m-test2.cpp:17
munir@ubuntu:~/prog/c$

This indicates that there is a potential memory leak in program at line 17 which is caused by dynamic memory allocation by calling malloc() and the program does not free the allocated memory. free() must be used in order to solve the problem. Here is the final version with no such memory leak:


// File: m-test3.cpp

#include <iostream>
#include <cstdlib>

#define SIZE 16

using namespace std;

bool isPalindrome(char *);

int main()
{
  char *str;
  while(true)
  {
    str = (char *)malloc(SIZE);
    cout << "Enter string to check Palindrome or quit to exit: ";
    cin >> str;
    if(strcmp(str, "quit") == 0)
    {
      free(str);
      break;
    }
    if(isPalindrome(str))
      cout << str << " is a Palindrome." << endl;
    else
      cout << str << " is NOT a Palindrome." << endl;
    free(str);
  }
  return 0;
}

bool isPalindrome(char *str)
{
  int str_len = strlen(str);
  for(int i = 0; i < str_len/2; i++)
    if(str[i] != str[str_len-i-1])
      return false;
  return true;
}

And running the test again:


munir@ubuntu:~/prog/c$ g++ m-test3.cpp -Wall -g -o m-test3
munir@ubuntu:~/prog/c$ ./m-test3
Enter string to check Palindrome or quit to exit: a
a is a Palindrome.
Enter string to check Palindrome or quit to exit: aaa
aaa is a Palindrome.
Enter string to check Palindrome or quit to exit: abc
abc is NOT a Palindrome.
Enter string to check Palindrome or quit to exit: aBbabBa
aBbabBa is a Palindrome.
Enter string to check Palindrome or quit to exit: aBbabBA
aBbabBA is NOT a Palindrome.
Enter string to check Palindrome or quit to exit: quit
munir@ubuntu:~/prog/c$ cat mtrace.log
= Start
@ ./m-test3:(__gxx_personality_v0+0x171)[0x8048915] + 0x804a378 0x10
@ ./m-test3:(__gxx_personality_v0+0x244)[0x80489e8] - 0x804a378
@ ./m-test3:(__gxx_personality_v0+0x171)[0x8048915] + 0x804a378 0x10
@ ./m-test3:(__gxx_personality_v0+0x244)[0x80489e8] - 0x804a378
@ ./m-test3:(__gxx_personality_v0+0x171)[0x8048915] + 0x804a378 0x10
@ ./m-test3:(__gxx_personality_v0+0x244)[0x80489e8] - 0x804a378
@ ./m-test3:(__gxx_personality_v0+0x171)[0x8048915] + 0x804a378 0x10
@ ./m-test3:(__gxx_personality_v0+0x244)[0x80489e8] - 0x804a378
@ ./m-test3:(__gxx_personality_v0+0x171)[0x8048915] + 0x804a378 0x10
@ ./m-test3:(__gxx_personality_v0+0x244)[0x80489e8] - 0x804a378
@ ./m-test3:(__gxx_personality_v0+0x171)[0x8048915] + 0x804a378 0x10
@ ./m-test3:(__gxx_personality_v0+0x1bd)[0x8048961] - 0x804a378
= End
munir@ubuntu:~/prog/c$ mtrace m-test3 mtrace.log
No memory leaks.
munir@ubuntu:~/prog/c$

So we just saw how easy is to detect memory leak using mtrace utility.

Source codes: m-test.cpp m-test2.cpp m-test3.cpp
Screen shot: here

Advertisements

21 Responses to “Finding Memory Leaks Using mtrace”

  1. Faisal Nasim Says:

    cool!

  2. Talha Says:

    very nicely written

  3. me Says:

    Whoaa!

    MS Ambassador .. using UBUNTU, GNU C Compiler, and alikes!!
    Where is the world coming to..!?

    Waisay, quite an informative post, I have been looking for some tuts on mtrace myself a couple of days back.. and this one is a pleasant intro read on the topic~!!

    Good work, keep it up, MS Amboo!

  4. munir Says:

    >MS Ambassador .. using UBUNTU, GNU C Compiler, and alikes!!
    >Where is the world coming to..!?

    LOL!
    Actually the ultimate goal is to destroy AAK‘s system which is the center of anti MS activities now a days and the idea is to attack the enemy with his own weapons. :-P

  5. Ayaz Ahmed Khan Says:

    Dude:

    You can’t even come close to penetrating my system, first of all. Secondly, you’ll have to do more than simply use Ubuntu, g++, cat, and whatever lame GUI editor you use to defeat me. Thirdly, only lamer coders who know jack about how memory allocation, in general, and dyname memory allocation, in particular, works depend on things like mtrace et al. You have gotta rise from that level of lame-ness to even think about defeating me.

    O, little one! I wish you luck.

  6. munir Says:

    only lamer coders who know jack about how memory allocation, in general, and dyname memory allocation, in particular, works depend on things like mtrace et al.

    Who said that memory allocation in g++ depends on mtrace?
    FYI mtrace() traces memory allocation using malloc(), realloc() and free() only. See man page on mtrace for more information.

    BTW your comments made me laugh so hard :D
    Keep dreaming my dear script kiddo and keep practice running meta-exploit and others’ perl scripts. May be you will be able to write a simple “Hello, World” by yourself before I actually come to penetrate your system.

  7. Ayaz Ahmed Khan Says:

    Dude, you clearly missed my point by a LONG shot. Read the part of my post about mtrace again, and again, and again, until you understand what the heck I’m talking about.

  8. munir Says:

    Whatever you say and whatever you mean, one thing is clear: Your Slackware is in danger and nothing can save it from me. :-)

  9. Ayaz Ahmed Khan Says:

    Dream on, boy! :-P

  10. Prashanth Gedde N Says:

    Very useful article.

    Keep posting!

  11. Azeem Says:

    Nice article and the last comment.lol

  12. Devraj Says:

    great article

  13. memory leaks tutorial Says:

    […] Memory Leaks Using mtraceA small tutorial on how to find memory leaks in C++ using mtrace.https://munir.wordpress.com/2006/08/05/finding-memory-leaks-using-mtrace/How to detect memory leaks with LoadRunner – visual tutorialHow to detect memory leaks with […]

  14. Alex Says:

    Your blog is interesting!

    Keep up the good work!

  15. chinmoy Says:

    it good…….working fine

  16. Jonas Says:

    Thank you for this useful info!

    I am curious about your Perl-script: how do you find out which source code line that belongs to each allocation / deallocation?

  17. Arun Kumar Says:

    Thanks for the work.. It is very well written..

  18. Arun Kumar Says:

    @Jonas: That perl script is kind of available. You might have it in /usr/bin. Check it out..

  19. SURAJ PASUPARTHY Says:

    very well written !

  20. mastavalons Says:

    Excellent article but I usually use Valgrind and Deleaker (Windows) for debugging .

  21. Memory Leaks – Atleast a feet firm on ground, like electrical circuits… Says:

    […] Refer to https://munir.wordpress.com/2006/08/05/finding-memory-leaks-using-mtrace/ […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: