WHITE PAPER Get the Better of Memory Leaks with Valgrind Whitepaper Memory leaks can cause problems and bugs in software which can be hard to detect. In this article we will discuss techniques and tools using which you can detect and fix memory leaks in your applications. Copyright 2007 and HCL proprietary material.all rights reserved. No part of this document may be reproduced, reused, modified or distributed, in whole or in parts, in any form by any means without prior written authorization of HCL.The information provided in this document is intended for the sole use of the recipient and not for any commercial purpose.all the information provided is on AS IS" basis and without warranties of any kind either express or implied or to any derived results obtained by the recipient from the use of the information in the document. HCL does not guarantee the sequence, accuracy or completeness of the information and will not be liable in any way to the recipient for any delays, inaccuracies, errors in, or omissions of, any of the information or in the transmission thereof, or for any damages what so ever arising there from.
Table of Contents 1. Introduction 2. Memory leak definition. Memory leak detection tools 4. Displaying Virtual Memory (VM) usage 5. Getting and installing Valgrind 4 6. Using Valgrind 4 7. Suppressing errors 4 8. Advantages of Valgrind 6 9. Limitations of Valgrind 6 10. Final Thoughts 6
1. Introduction Today softwares are written with great innovation and care. Extreme care is taken to ensure that the software performs well, whether it is on the User Interface (GUI) front, features or performance front. With the growing advent of applications being developed and ported on GNU/Linux it becomes essential for a GNU/Linux developer to develop software which caters to the user s need and performs well on a variety of hardware on which GNU/Linux runs. With the embedded domain on GNU/Linux really catching up and the growing number of applications being developed for embedded devices like mobiles, PDAs, gaming consoles etc., it becomes essential to have software which utilizes the limited memory available on these systems and makes best use of it. In spite of great care being taken for developing quality software, developers are bound to make mistakes, thus resulting in bugs in the software. One such bug which can cause problems on PC and create havoc in embedded devices is Memory Leak. In this article, we will discuss about a free and opensource tool called Valgrind using which you can easily detect and fix memory leaks in your applications. 2. Memory leak definition According to Valgrind manual: A memory leak is a part of memory that has been allocated but not freed after its usage or when pointer to a memory allocation is deleted, thereby making the memory unusable. The more often this memory leak occurs the more valuable memory will be wasted and taken away from other processes thereby affecting the whole system. If your applications usage exceeds the virtual memory size, it will crash the system. According to Valgrind manual, some of the common memory related errors are: Use of uninitialized memory. Reading/writing memory after it has been freed. Reading/writing off the end of malloced blocks. Reading/writing inappropriate areas on the stack. Memory leaks where pointers to malloced blocks are lost forever. Mismatched use of malloc/new/new[] vs free/delete/delete[]. Some misuses of the POSIX pthreads API.. Memory leak detection tools Various tools are available for detecting memory leaks and other bugs in your programs. The most popular and well known tools are Purify (IBM) and Valgrind. IBM s Purify runs on GNU/Linux and Windows but is proprietary and expensive. Being tux lovers we will focus on a free, open-source memory-leak detection tool called Valgrind. 4. Displaying Virtual Memory (VM) usage To begin with, let s check out the memory usage of your application using a commonly used utility ps available on all *nix platforms. ps command displays the process status. Using the various options available with it, it can be used for displaying an application s process-id, memory usage, cpu-utilization etc. For example, to display the process name, process id and VM usage of currently running applications in the shell, following command should be used: $ ps -o cmd,pid,vsize Numerous options for the ps command are available through which you can view resource utilization of an
application. If you have installed GNOME, you can use gnomesystem-monitor command to view the process id, VM usage etc. in a GUI window. Using the above you can check the VM usage of your application, but to dig deep inside your code for memory leaks, you need Valgrind. Tip: You can also use 'vmstat' command to display the VM usage of your applications. 5. Getting and installing Valgrind You can download the latest version of Valgrind from t h i s m o n t h s L F Y C D o r f r o m http://valgrind.org/downloads/source_code.html. For installing Valgrind first extract it: $ tar jxvf valgrind-version.tar.bz2 $ cd valgrind-version Follow the three heavenly steps: $./configure $ make $ make install This would install Valgrind onto your system. 6. Using Valgrind To check your application for memory leaks, place valgrind before the application name while executing the application. $ valgrind <application-name> Valgrind can be used on existing GNU/Linux commands, for example: $ valgrind ps This will display the ps command output along with detailed report by valgrind. Valgrind includes various tools which can be used for detecting different types of problems. These are: memcheck: checks for memory leaks, accesses to uninitialized memory etc. addrcheck: similar to memcheck but doesn't perform thorough memory checking, runs faster and uses less memory than memcheck. cachegrind: cachegrind is a cache simulator. massif: massif is a heap profiler. lackey: lackey is a sample tool that can be used as a template for generating your own tools. Tip: You can check out the Valgrind man page for more details and options. To specify the tool to be used, enter the following command: $ valgrind --tool=<toolname> <application-name> For e.g. for using the memcheck tool on an application a.out, the command would be: $ valgrind --tool=memcheck./a.out 7. Suppressing errors Valgrind, by default reports errors in all programs/libraries installed on your GNU/Linux system on which your application is dependent. Since, we are interested in our own application; we can easily suppress these errors by creating a.supp file and giving its path while running Valgrind. Valgrind reads this file at startup and suppresses errors having entry is in the.supp file. $ valgrind --suppressions=./suppfile.supp <application-name> Tip: Details about the format of suppression files can be found in the Valgrind manual. A simple example using Valgrind Let s explore the beauty of Valgrind using a simple example given below (Listing 1): ------------------------------CODE--------------------------- 4
Listing 1: #include <stdio.h> #include <string.h> int main() { char *p = (char *)malloc(20*sizeof(char)); strcpy(p, linux rocks! ); printf( %s\n, p); return 0; } -----------------------------CODE---------------------------- In this program, we have allocated a memory of 20 bytes but it is not freed before the program exits. Let s analyze this program using Valgrind. Compile this program using the following command: $ gcc -g -o listing1 listing1.c Run the program using valgrind: $ valgrind --tool=memcheck./listing1 This will display a brief memory leak summary about our program: ERROR SUMMARY: 0 errors from 0 contexts (suppressed 18 from 1) malloc/free: in use at exit: 20 bytes in 1 blocks. malloc/free: 1 allocs, 0 frees, 20 bytes allocated. LEAK SUMMARY: definitely lost: 20 bytes in 1 blocks. possibly lost: 0 bytes in 0 blocks. still reachable: 0 bytes in 0 blocks. suppressed: 0 bytes in 0 blocks. The memory leak summary clearly displays that we have allocated 20 bytes using malloc() but we haven t freed the memory after use. The above memory leak summary is very brief and doesn t display the sourcecode where we have allocated the memory. For detailed memory-leak report, plug-in the following command: $ valgrind --tool=memcheck --leak-check=full./listing1 This command displays the following output: ERROR SUMMARY: 0 errors from 0 contexts (suppressed 18 from 1) malloc/free: in use at exit: 20 bytes in 1 blocks. malloc/free: 1 allocs, 0 frees, 20 bytes allocated. 20 bytes in 1 blocks are definitely lost in loss record 1 of 1 at 0x1B8FEA5: malloc (vg_replace_malloc.c:149) by 0x804875: main (listing1.c:4) LEAK SUMMARY: definitely lost: 20 bytes in 1 blocks. possibly lost: 0 bytes in 0 blocks. still reachable: 0 bytes in 0 blocks. suppressed: 0 bytes in 0 blocks From the above output we can conclude that 20 bytes of memory was allocated in listing1.c at line 4 but was not freed after use. So, the correct code would be: --------------------------------CODE------------------------- Listing 2: #include <stdio.h> #include <string.h> int main() { char *p = (char *)malloc(20*sizeof(char));/* Allocate 20 bytes of memory */ strcpy(p, linux rocks! ); printf( %s\n, p); free(p); /* Free the allocated memory */ return 0; } -----------------------------CODE---------------------------- 5
The Valgrind output for the above program is: ERROR SUMMARY: 0 errors from 0 contexts (suppressed 18 from 1) malloc/free: in use at exit: 0 bytes in 0 blocks. malloc/free: 1 allocs, 1 frees, 20 bytes allocated. The above output indicates that all the allocates memory has been freed and there are no memory leaks in the application. You can also save the Valgrind output to a log file and view the memory leak details using a graphical frontend such as Alleyoop as shown in Figure 1. Valgrind can be used with other tools like GDB (GNU Debugger), KDevelop (as a plug-in). It can be used with almost any kind of software written in any language. It can be used as a platform for writing new debugging tools. Valgrind is free, open-source and available under GPL 2. Several graphical front-ends are available for Valgrind, some of which include Alleyoop, Valgui, GNUGrind, KDevelop (with Valgrind as a plug-in) 8. Limitations of Valgrind Every software has some limitations and Valgrind is no exception. Application runs 25 to 50 times slower through Valgrind. Memory consumption is increased while running the application through Valgrind. Highly optimized code can sometimes cheat Valgrind. Works only on GNU/Linux, x86 platforms. So, by using Valgrind and various tools available with it, you can easily detect and fix memory leaks and other memory-related bugs in your applications. 8. Advantages of Valgrind Valgrind currently supports all major GNU/Linux distributions on x86 architecture. Some of its benefits include: Valgrind works directly with executables, so there is no need to modify, recompile or relink your applications. Valgrind can be used to debug small as well as large applications. Target Audience: GNU/Linux Programmers 9. Final Thoughts Memory related bugs in software can be hard to detect and fix. Using Valgrind and various graphical front-ends available with it, you can easily detect and fix memory leaks in your application. Efficient utilization of memory, especially on embedded systems is a must and Valgrind allows you to achieve just that! Refrences: This articles includes references from the Valgrind Manual and is licensed under GNU Free 6
Documentation License. For details about the GNU F r e e D o c u m e n t a t i o n L i c e n s e, v i s i t http://www.gnu.org/copyleft/fdl.html Author Profile Ramandeep Singh. Working as Lead Engineer at HCL Technologies Ltd and love singing, gaming, tinkering with different flavors of Unix and GNU/Linux. I can be contacted at ramandeeps@noida.hcltech.com Hello there. I am from HCL Technologies. We work behind the scenes, helping our customers to shift paradigms and start revolutions. We use digital engineering to build superhuman capabilities. We make sure that the rate of progress far exceeds the price. And right now, 45,000 of us bright sparks are busy developing solutions for 500 customers in 17 countries across the world. 7