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.
Certain symptoms indicate the presence of a possible leak when:
- Malloc returns with
errnoset toENOMEM. - 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
pscommand) 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.
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 ALLOCATOR | Detailed explanation in the "Developing and Porting C and C++ Applications on AIX" IBM Redbook |
|---|---|---|
| 3.1 | 3.1 memory allocator | Section 4.2.1, The 3.1 memory allocator |
| NULL | Default memory allocator | Section 4.2.2, The default memory allocator |
| buckets | Default memory allocator with the malloc buckets extension | Section 4.2.3, The default memory allocator with the malloc buckets extension |
| debug | Debug memory allocator | Section 4.2.4, The debug memory allocator |
| user:archive_name | User-defined memory allocator | Section 4.2.5, The user-defined malloc replacement |
You should be aware that MALLOCDEBUG assumes the use of the default allocator.
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:n | n is the number of bytes to which memory is aligned. See Resources for more Information. |
| postfree_checking | postfree_checking causes MALLOCDEBUG to report attempts to access freed memory, and then abort the program. |
| validate_ptrs | If 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_handling | When 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. |
| continue | continue reports errors, but it doesn't ABEND the program. This is a useful feature available in AIX Version 5.3 |
| stack_depth:n | stack_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.
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. |
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.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample program and parsing script for debug malloc | au-mallocdebug.zip | 2KB | HTTP |
Information about download methods
Learn
- Developing and Porting C and C++ Applications on AIX: Read this IBM Redbook if you are an experienced UNIX® application developer and are new to AIX.
- "Navigating "C" in a "leaky" boat? Try Purify" (developerWorks, Aug 2006): Read about how to debug memory leaks using IBM Rational Purify.
- General Programming Concepts: Writing and Debugging Programs: Read about debugging applications that are mismanaging memory allocated via the malloc() subroutine.
- Memory leaks: Learn the definition of memory leaks, about potential consequences, and programming consequences.
- The AIX and UNIX developerWorks zone provides a wealth of information relating to all aspects of AIX systems administration and expanding your UNIX skills.
- New to AIX and UNIX: Visit the New to AIX and UNIX page to learn more about AIX and UNIX.
- developerWorks
technical events and webcasts: Stay current with developerWorks technical events and webcasts.
- AIX 5L Wiki: A collaborative environment for technical information related to AIX.
- Podcasts: Tune in and catch up with IBM technical experts.
Get products and technologies
- IBM trial software: Build your next development project with software for download directly from developerWorks.
Discuss
-
Participate in the AIX and UNIX forums:
- AIX 5L -- technical
- AIX for Developers Forum
- Cluster Systems Management
- IBM Support Assistant
- Performance Tools -- technical
- Virtualization -- technical
- More AIX and UNIX forums
- Participate in the developerWorks
blogs and get involved in the developerWorks community.

Manish 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 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.



