Debugging applications that are mismanaging memory allocated via the malloc() subroutine can be difficult and tedious. Most often, the problem is that data is written past the end of an allocated buffer. Since this has no immediate consequence, problems don't become apparent until much later when the space that was overwritten (usually belonging to another allocation) is used and no longer contains the data originally stored there.
The AIX memory subsystem includes an optional debug capability to allow users to identify memory overwrites, overreads, duplicate frees and reuse of freed memory allocated by malloc(). Activation and configuration of the Debug Malloc capability is available at process startup via the MALLOCTYPE and MALLOCDEBUG environment variables.
Memory problems detected by Debug Malloc result in an abort() or a segmentation violation (SIGSEGV). In most cases, when an error is detected the application stops immediately and a core file is produced.
Debug Malloc is only available for applications using the default allocator. It is not supported for the AIX 3.1 malloc.
Debug Malloc is not enabled by default. It is enabled and configured by setting the following environment variables:
To enable Debug Malloc with default settings, set the MALLOCTYPE environment variable as follows:
To enable Debug Malloc with user-specified configuration options, set both the MALLOCTYPE and MALLOCDEBUG environment variables as follows:
where options is a comma-separated list of one or more predefined configuration options, as described in the next section of this document.
If the application being debugged calls malloc() frequently, it may be necessary to enable the application to access additional memory via use of the the ulimit command and the -bmaxdata option of the ld command. Please refer to the section entitled "Disk and Memory Considerations" later in this document for additional information.
The MALLOCDEBUG environment variable can be used to provide Debug Malloc with one or more of the following predefined configuration options:
Each of these options is described in detail later in this document.
The MALLOCDEBUG environment variable is set using the following syntax:
MALLOCDEBUG=[[ align:n | postfree_checking | validate_ptrs | override_signal_handling | allow_overreading | report_allocations | record_allocations],...]
More than one option can be specified (and in any order) as long as options are comma-separated, as in the following example:
MALLOCDEBUG=align:0,validate_ptrs,report_allocations
Each configuration option should only be specified once when setting MALLOCDEBUG. If a configuration option is specified more than once per setting, only the final instance will apply.
It is important to remember that the MALLOCDEBUG environment variable will only be recognized by the malloc subsystem if MALLOCTYPE is set to "debug", as in the following example:
Each of the MALLOCDEBUG options is described in detail below:
NOTES:
- Please refer to the section entitled "Additional Information about align:n Option" later in this document for additional information about the align:n option.
- For allocated space to be word aligned, specify align:n with a value of 4.
- Applications built using DCE components are restricted to a value of 8 for the align:n option. Values other than 8 may result in undefined behavior.
NOTE:
- Specifying the postfree_checking option automatically enables the validate_ptrs option.
If the calling program is blocking or catching the SIGSEGV and/or the SIGIOT signals, Debug Malloc will be prevented from reporting errors. The Debug Malloc override_signal_handling option provides a means of addressing this situation without recoding and rebuilding the application.
If the Debug Malloc override_signal_handling option is specified, Debug
Malloc will perform the following actions upon each call to one of the memory
allocation routines (malloc(), free(), realloc() or calloc()):
If an application signal handler modifies the action for SIGSEGV between memory allocation routine calls and then attempts an invalid memory access, Debug Malloc will be unable to report the error (the application will not exit and no core file will be produced).
NOTES:
- The override_signal_handling option may be ineffective in a threaded application environment because Debug Malloc uses sigprocmask() and many threaded processes use pthread_sigmask().
- If a thread calls sigwait() without including SIGSEGV and SIGIOT in the signal set and Debug Malloc subsequently detects an error, the thread will hang because Debug Malloc can only generate SIGSEGV or SIGIOT.
- If a pointer to invalid memory is passed to a kernel routine, the kernel routine will fail and usually return with errno set to EFAULT. If the application is not checking the return from the system call, this error can go undetected.
NOTES:
- Specifying the report_allocations option automatically enables the record_allocations option.
- One allocation record will always be listed for the atexit() handler that dumps the allocation records.
Each allocation record will be retained until the memory associated with it is freed.
The following formula can be used to calculate how many bytes of overreads and/or overwrites Debug Malloc will allow for a given allocation request when MALLOCDEBUG=align:n and size is the number of bytes to be allocated:
((((size / n) + 1) * n) - size) % n
The following examples demonstrate the effect of the align:n option on the application's ability to perform overreads and/or overwrites with Debug Malloc enabled:
MALLOCTYPE=debug MALLOCDEBUG=align:2,postfree_checking,override_signal_handling
In this case, Debug Malloc will handle overreads and overwrites as follows:
MALLOCTYPE=debug MALLOCDEBUG=align:0,postfree_checking,override_signal_handling
In this case, Debug Malloc will allow 0 bytes of overreads and/or overwrites in all cases, regardless of the number of bytes requested.
All memory problems detected by Debug Malloc result in an abort() or a segmentation violation (SIGSEGV). If Debug Malloc is enabled and the application runs to completion without an abort() or a segmentation violation, then the malloc subsystem did not detect any memory problems.
In most cases, when an error is detected the application stops immediately and a core file is produced. If the error is caused by an attempt to read or write past the end of allocated memory or to access freed memory, then a segmentation violation will occur at the instruction accessing the memory. If a memory routine (malloc(), free(), realloc() or calloc()) detects an error, a message is displayed and abort() is called.
Because of the extra work involved in making various run-time checks, malloc subsystem performance will degrade considerably with Debug Malloc enabled, but not to the point that applications will become unusable. Because of this performance degradation, applications should only be be run with Debug Malloc enabled when trying to debug a known problem. Once the problem is resolved, Debug Malloc should be turned off to restore malloc subsystem performance.
With Debug Malloc enabled, the malloc subsystem will consume significantly more memory. Each malloc() request is increased by "4096+2*sizeof(unsigned long)" and then rounded up to the next multiple of PAGESIZE. Debug Malloc may prove to be too memory-intensive to use for some large applications, but for the majority of applications that need memory debugging, the extra use of memory should not cause a problem.
If the application being debugged calls malloc() frequently, it may encounter memory usage problems with Debug Malloc enabled which may prevent the application from executing properly in a single segment. If this occurs, it may be helpful to enable the application to access additional memory via use of the the ulimit command and the -bmaxdata option of the ld command.
For the purpose of running with Debug Malloc enabled, the ulimit should be set for both data (-d) and stack (-s) as follows:
ulimit -d unlimited ulimit -s unlimited
The -bmaxdata option should be specified as -bmaxdata:0x80000000 in order to reserve the maximum of 8 segments for a 32-bit process.
When Debug Malloc is turned off, the default values for ulimit and -bmaxdata should be restored.
The ulimit command and the -bmaxdata option are discussed in detail in Chapter 8, Large Program Support.
Debug Malloc is only available for applications using the default allocator. It is not supported for the AIX 3.1 malloc.
Debug Malloc is not appropriate for full-time, constant or system-wide use. Although it is designed for minimal performance impact upon the application being debugged, it may have significant negative impact upon overall system throughput if it is used widely throughout a system. In particular, setting MALLOCTYPE=debug in the /etc/environment file (to enable Debug Malloc for the entire system) is unsupported, and will likely cause significant system problems such as excessive use of paging space. Debug Malloc should only be used to debug single applications or small groups of applications at the same time.
In addition, please note that Debug Malloc is not appropriate for use in some debugging situations. Because Debug Malloc places each individual memory allocation on a separate page, programs that issue many small allocation requests will see their memory usage increase dramatically. These programs may encounter new failures as memory allocation requests are denied due to a lack of memory or paging space. These failures are not necessarily errors in the program being debugged, and they are not errors in Debug Malloc.
One specific example of this is the X server, which issues numerous tiny allocation requests during its initialization and operation. Any attempt to run the X server (via the X or xinit commands) with Debug Malloc enabled will result in the failure of the X server due to a lack of available memory. This is a known limitation of the Debug Malloc tool. However, X clients in general will not encounter functional problems running under Debug Malloc. To use Debug Malloc on an X client program, take the following steps:
Chapter 8, Large Program Support
malloc, free, realloc, calloc, mallopt, mallinfo, alloca, or valloc Subroutine in AIX 5L Version 5.1 Technical Reference: Base Operating System and Extensions Volume 1.