Isolate and resolve memory leaks using MALLOCDEBUG on AIX Version 5.3

A helpful tool for a tedious task

Take advantage of MALLOCDEBUG, the malloc subsystem monitoring tool shipped with AIX® Version 5.3 that helps you isolate memory leaks. Memory leaks can be tough and costly problems to solve, so it makes sense to use good tools to clearly point out and understand where the leaks are coming from. Study the example code presented in this article and use it as an approach to tackle memory leaks.

Share:

Katiyar Manish, Software Engineer, IBM

Photo of Katiyar ManishManish Katiyar works as a software engineer for IBM India Software Labs. He has worked for IBM for the past two years, focusing on SARPC. He also has experience on data warehousing tools (Ab-Initio). Manish holds a Bachelor of Technology degree in chemical engineering from the Indian Institute of Technology Kharagpur in India. You can contact him at manish.katiyar@in.ibm.com.



Vaarun Vijairaghavan (vivaarun@in.ibm.com), System Software Engineer, IBM

Photo of Vaarun VijairaghavanVaarun Vijairaghavan is a System Software Engineer for the IBM India Software Labs in Pune, India. He has worked as a developer with the Distributed Computing Environment (DCE) Project for the past three years. His research interests include network security, fault tolerance, and distributed computing. He holds a Bachelor of Computer Engineering degree from the University of Pune. You can contact him at vivaarun@in.ibm.com.



25 September 2007 (First published 21 November 2006)

Also available in Chinese Russian

Introduction

Dynamic memory allocation is a boon while programming your application. It helps allocate the required memory at the run time of the program, rather than allocating at the start of the process. However, it is very important to efficiently manage this memory. In large, complex applications, memory leaks are a very common problem. Memory leaks occur when a piece of memory previously allocated is no longer needed or accessible, but still not freed and thus results in lack of total available memory to the process. While good programming practices ensure minimal leaks, it has been our experience that when the same blocks of memory get handled by numerous functions, memory leaks tend to occur. This is especially true when error paths are hit.

This article outlines an approach you can use while tackling memory leaks, and it discusses how to take advantage of the MALLOCDEBUG tool that is supplied with AIX®.

Why memory leaks are tough problems to solve

You can free a piece of memory at different times in the life of an application based on the conditions it encounters. The application has to be designed so that it knows when a block of memory is ready to be freed, and performs the action sooner rather then later. Based on the flow of control, the memory can be freed at different points in the code. It is extremely important that all such control flows get covered, not just the most hit code flow path.

At the same time, freeing memory before it is ready to be freed can be fatal. Thus, a good understanding of the control flow within the application is extremely useful for understanding where the block gets ready to be freed.

Detecting memory leaks

Certain symptoms indicate the presence of a possible leak when:

  • Malloc returns with errno set to ENOMEM.
  • A core dump occurs, and one of the functions in the stack is from the malloc subsystem.
  • The process size is large when it cores compared to when it is running normally.
  • The process size (which can be seen through the ps command) grows rapidly.

If there are indications that you have a memory leak, it's a good idea to use a memory monitoring tool. There are some third party tools, such as Zerofault and IBM Rational® Purify®, but this article discusses the MALLOCDEBUG tool that is supplied with AIX.

Using MALLOCDEBUG to report memory leaks

MALLOCDEBUG is an easy-to-use malloc subsystem monitoring tool. You can easily enable debugging for the malloc subsystem for a particular application by using two environment variables, MALLOCDEBUG and MALLOCTYPE. You need to export these variables to the shell from which the application will be launched. The error report is written to stderr in AIX Version 5.3.

MALLOCTYPE

The MALLOCTYPE variable determines which malloc subsystem should be used, and whether debugging is to be enabled or not. Table 1 below shows the various values that MALLOCTYPE can be set to. See Resources for a link to the "Developing and Porting C and C++ Applications on AIX." IBM Redbook.

Table 1. MALLOCTYPE variables
MALLOCTYPE=MEMORY ALLOCATORDetailed explanation in the "Developing and Porting C and C++ Applications on AIX" IBM Redbook
3.13.1 memory allocatorSection 4.2.1, The 3.1 memory allocator
NULLDefault memory allocatorSection 4.2.2, The default memory allocator
bucketsDefault memory allocator with the malloc buckets extensionSection 4.2.3, The default memory allocator with the malloc buckets extension
debugDebug memory allocatorSection 4.2.4, The debug memory allocator
user:archive_nameUser-defined memory allocatorSection 4.2.5, The user-defined malloc replacement

You should be aware that MALLOCDEBUG assumes the use of the default allocator.

MALLOCDEBUG

The MALLOCDEBUG variable can take multiple comma-separated values from the list in Table 2 below.

Table 2. The MALLOCDEBUG variable
MALLOCDEBUG=Brief explanation
Align:nn is the number of bytes to which memory is aligned. See Resources for more Information.
postfree_checkingpostfree_checking causes MALLOCDEBUG to report attempts to access freed memory, and then abort the program.
validate_ptrsIf a pointer that was previously not allocated by malloc is passed to the free() call, an error message is thrown and the program is aborted.
override_signal_handlingWhen MALLOCDEBUG detects memory errors, it forces the program to core using SIGSEGV or SIGABRT. Setting override_signal_handling ensures that the program terminates and core, even if these signals have been handled by the application.
allow_overreading allow_overreading ignores overreads.
report_allocations report_allocations reports all memory allocations that were not freed at application exit.
record_allocations record_allocations reports all memory allocations.
continuecontinue reports errors, but it doesn't ABEND the program. This is a useful feature available in AIX Version 5.3
stack_depth:nstack_depth:n reports the error stack to a depth of n, instead of the default 6.

Of these, the option report_allocations is most relevant to use, as it gives you a list of leaks detected in the application.

Example

In this section, you'll examine an example and several sample code listings to illustrate how you can use MALLOCDEBUG. The source code for this example is available in the Download section.

Listing 1. MALLOCDEBUG and MALLOCTYPE settings exported to the shell
                /home/user> export MALLOCTYPE=debug /home/user> export
                MALLOCDEBUG=report_allocations
Listing 2. Output from the program
 /home/user> ./stud
                2>mal_dbg_stud Student Name: Manish Subjects # Maths English Student Name: Vaarun
                Subjects # Chemistry Physics Student Name: Sandeep Subjects # Biology Maths ......
                ...... ...... ...... Student Name: Govind Subjects # Physics Biology Student Name:
                Manish Subjects # Maths English Current allocation report: Allocation #0: 0x2000EFE8
                Allocation size: 0x14 Allocation traceback: 0xD0371F64 malloc 0xD0322194 init_malloc
                0xD0323224 malloc 0x10000BE4 initialize_leaky Allocation #1: 0x20010FF0 Allocation
                size: 0xA Allocation traceback: 0xD0371F64 malloc 0x10000C08 initialize_leaky
                0x10000DD4 main 0x100001B4 __start Allocation #2: 0x20012FF0 Allocation size: 0xA
                Allocation traceback: 0xD0371F64 malloc 0x10000C08 initialize_leaky 0x10000DD4 main
                0x100001B4 __start ...... ...... ...... ...... Allocation #17: 0x20030FF0 Allocation
                size: 0x10 Allocation traceback: 0xD0371F64 malloc 0x100008F4 getnode 0x10000B08
                insert 0x10000DDC main Allocation #18: 0x20032FF8 Allocation size: 0x8 Allocation
                traceback: 0xD0371F64 malloc 0x10000894 allocate_for_dbl_ptr 0x10000910 getnode
                0x10000B08 insert Allocation #19: 0x20034FE8 Allocation size: 0x14 Allocation
                traceback: 0xD0371F64 malloc 0x10000A5C allocate_name 0x10000B18 insert 0x10000DDC
                main Allocation #22: 0x2003AFF0 Allocation size: 0x10 Allocation traceback:
                0xD0371F64 malloc 0x100008F4 getnode 0x10000B3C insert 0x10000DDC main ...... ......
                ...... ......

The output format of MALLOCDEBUG is not very user friendly. It simply prints the function stack that calls malloc for every allocated block that was not freed. It also returns the size of the block, and the value of the pointer that was returned by malloc.

To make the above output more intelligible, we wrote a sample script. (See the Download section. Please note that this is a sample script meant to be used on outputs similar to the example program.) Listing 3 below shows the output after we ran the script on the above set of stacks.

Listing 3. Parsing the output of MALLOCDEBUG by script
 /home/user>
                ./format_mallocdebug_op.ksh Usage : ./stack.ksh stackfile /home/katiyar/DW>
                ./format_mallocdebug_op.ksh ./mal_dbg_stud | tee ./mal_dbg_stud_formatted Parsing
                output from debug malloc ... Analyzed 50 stacks ... main insert allocate_subjects
                malloc ################################ 220 bytes leaked in 22 Blocks
                ################################ main insert allocate_name malloc
                ################################ 220 bytes leaked in 11 Blocks
                ################################ __start main initialize_leaky malloc
                ################################ 190 bytes leaked in 16 Blocks
                ################################ main insert getnode malloc
                ################################ 176 bytes leaked in 11 Blocks
                ################################ insert getnode allocate_for_dbl_ptr malloc
                ################################ 88 bytes leaked in 11 Blocks
                ################################ initialize_leaky malloc init_malloc malloc
                ################################ 20 bytes leaked in 1 Blocks
                ################################

Investigation should begin from the biggest leaks. The first stack above shows that main calls insert, which calls allocate_subjects. allocate_subjects is allocating a block of memory by calling malloc, and this block is never being freed. The script output mentions that 220 bytes have been leaked cumulatively through 22 individual allocations. This means you should look at places in the code where we have allocated 10 bytes of data in allocate_subjects function and check if all its instances have been freed. A careful analysis of the program points you to the location where the memory block in question should be freed.

A similar analysis was done for each stack in the report, and a fix was made for it. In the program, the fixes come into effect if the FREE_BLOCKS=1 environment variable is exported to the shell before running the program.

Listing 4. Output after freeing the malloced blocks
 /home/katiyar/DW> ./stud
                Student Name: Manish Subjects # Maths English Student Name: Vaarun Subjects #
                Chemistry Physics Student Name: Sandeep Subjects # Biology Maths ...... ......
                ...... ...... Student Name: Govind Subjects # Physics Biology Student Name: Manish
                Subjects # Maths English Current allocation report: Total allocations: 0.

Conclusion

While servicing software on customer machines, it has been noted that MALLOCDEBUG is one of the few malloc subsystem monitoring tools available. In order to avoid a host of malloc errors when the customer is requested for MALLOCDEBUG logs while getting service on a machine, it can be very beneficial to test your application with MALLOCDEBUG before shipping it to a customer. We hope this article has provided a useful introduction to the developers and service engineers who have to deal with memory leaks on customer machines.


Download

DescriptionNameSize
Sample program and parsing script for debug mallocau-mallocdebug.zip2KB

Resources

Learn

Get products and technologies

  • IBM trial software: Build your next development project with software for download directly from developerWorks.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into AIX and Unix on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=AIX and UNIX
ArticleID=175547
ArticleTitle=Isolate and resolve memory leaks using MALLOCDEBUG on AIX Version 5.3
publish-date=09252007