Debugging Dynamic Memory Usage Errors Using HP WDB HP Part Number: 5900-1474 Published: January 2011 Edition: 7
© Copyright 2007-2011 Hewlett-Packard Development Company, L.P Legal Notices The information in this document is subject to change without notice. Hewlett-Packard makes no warranty of any kind with regard to this manual, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose.
Contents Introduction.............................................................................................................5 Intended Audience...................................................................................................5 Typographic Conventions...........................................................................................5 Related Information...................................................................................................6 Prerequisites.............
Supported Modes of Memory-debugging in WDB......................................................59 Debugging in the Interactive Mode......................................................................59 Debugging in Batch Mode..................................................................................60 Environment Variables for Batch Memory-Debugging ........................................60 Enabling and Disabling Batch Mode Memory-Debugging ............................
Introduction HP Wildebeest Debugger (WDB) is an HP-supported implementation of the open source debugger GDB. Apart from the normal debugging functions, it also enables you to debug memory-related errors in a program. HP WDB supports memory-debugging (using Run Time Checking (RTC)) of source-level programs written in HP C, HP aC++, and Fortran 90 on Itanium®-based systems running HP-UX 11i v2, or HP-UX 11i v3, and PA-RISC systems running HP-UX 11.
ENVIRONMENT VARIABLE The name of an environment variable, for example, PATH. ERROR NAME The name of an error, usually returned in the errno variable. Variable The name of a placeholder in a command, function, or other syntax display that you replace with an actual value. <> The contents are optional in syntax. If the contents are a list separated by |, you must choose one of the items. [] The contents are optional in syntax.
Prerequisites Following are the prerequisites for debugging memory-related problems in WDB: • The memory-debugging feature in WDB is dependent on the availability of the dynamic Linker Version B.11.19. • WDB uses the heap debugging library, librtc.[sl|so], to enable memory-debugging support. The librtc.[sl|so] library is a part of the HP WDB product.
Heap Corruption A heap corruption occurs when an application erroneously overwrites some of the data in the heap. Heap corruption can result in data corruption, memory corruption, or both. When an application inadvertently uses the erroneously overwritten data in the heap, it results in data corruption in the application. Data corruption can lead to unpredictable program behavior.
When to Suspect a Memory Leak? You must suspect a memory leak in an application if the system runs out of swap space, runs slower, or both. Memory leaks in an application increase the memory consumption in an application. When the memory consumed by the application exceeds the resource limits set by the kernel, the application fails with out-of-memory errors. WDB enables you to detect out-of-memory conditions through runtime memory checking.
The typical causes for logical leaks are listed below: ◦ Leaks caused by premature allocation of memory The application allocates the memory much ahead of the actual use of the allocated memory. ◦ Leaks caused by delayed de-allocation The application delays the freeing the allocated block beyond the actual use of the allocated memory. ◦ Leaks caused by failure to utilize allocated memory The application allocates memory, but fails to use the allocated memory.
WDB provides the interactive, batch, and attach modes for debugging memory-related problems. See “Supported Modes of Memory-debugging in WDB” (page 59) for more information on the supported modes for debugging. HP aC++/ HP C Compiler Runtime Checking Options The HP aC++/HP C compiler also provides options for enabling memory debugging using WDB in Integrity Systems. This feature is supported only on Integrity Systems.
Memory Checking Analysis for User Defined Memory Management Routines Many user applications have their own memory management routines. These custom allocator routines are either user defined or sometimes wrappers to the default memory management routines. Memory checking features have been extended for user defined memory management routines. Memory leak, prole of heap memory, or memory errors can be obtained for user defined memory management routines.
WDB supports the following heap-analysis profiles: • Snapshot Profile • Incremental Heap Profile • Arena Profile NOTE: Heap profiling must be enabled to view heap reports. The set heap-check on command enables heap profiling also. Snapshot Profile The snapshot profile displays the outstanding heap allocations at a specific instant (probe point) at runtime. It does not display the blocks that are already freed before the probe point. Table 4 lists the basic commands used for heap profiling.
(gdb) b 3. Run the program by entering the following command: (gdb)run 4. When the program is stopped at a breakpoint, enter the following info heap command: (gdb) info heap The following output is displayed: Analyzing heap ...done Actual Heap Usage: Heap Start = 0x40408000 Heap End = 0x4041a900 Heap Size = 76288 bytes Outstanding Allocations: 41558 bytes allocated in 28 blocks No. Total bytes Blocks Address 0 34567 1 4096 2 1234 3 245 [...
5. To view a specific allocation, specify the allocation number as an argument to the info heap command. For example: (gdb) info heap 1 4096 bytes at 0x7bd63000 (9.86% of all bytes allocated) in bar () at test.c:108 in main () at test.c:17 in _start () in $START$ () When multiple blocks are allocated from the same call stack, WDB displays additional information similar to the following: (gdb) info heap 3 245 bytes in 8 blocks (0.
Example 1 Filtered Heap Reporting for Allocations Exceeding at a Particular Call-Site Sample Program 1 2 3 4 5 6 7 8 9 10 11 12 #include #include main() { int i, *arr[1000]; for (i=0; i < 1000; i++) arr[i] = malloc (49); malloc (30); set_brkpt_here(0) exit(0); } Sample Debugging Session $ gdb minheap (gdb) b set_brkpt_here (gdb) set heap-check min-heap-size 31 (gdb) run (gdb) info heap Analyzing heap ... 49000 bytes allocated in 1000 blocks No.
Table 5 Commands for Incremental Heap-Profiling Command Description set heap-check interval Starts the incremental heap growth profile. All allocations prior to the execution of this command are ignored. If incremental heap growth profile is already on, executing this command resets the counters and starts a fresh collection. The interval is specified in seconds. set heap-check repeat Enables you to specify the number of intervals for which WDB must collect the incremental heap growth.
Example 2 Incremental Heap Profile Sample Program $ cat testincremental.c 1 #include 2 #include
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 func1(); sleep (1); } /* 2 interval records */ marker1(); for (repeat = 0; repeat < 2; repeat++) for (i = 0; i < 2; i++) { func2(); sleep (1); } /* 4 (3 old and 1 new) interval records; as the repeat count of 100 has been exceeded.
(gdb) file testincremental Reading symbols from testincremental.. done. (gdb) set heap-check interval 1 (gdb) set heap-check repeat 2 (gdb) b marker1 Breakpoint 1 at 0x4000000000000e50:0: file testincremental.c, line 9 from testincremental (gdb) r Starting program: testincremental Breakpoint 1, marker1 () at testincremental.c:9 {} (gdb) info heap-interval Analyzing heap ...
WDB enables you to view the following memory-usage statistics: • High level memory-usage statistics of a process • High level memory-usage statistics of each arena • Block level and overall memory-usage statistics of each arena • Block level and overall memory-usage statistics of each arena along with the allocated stack trace for each allocated block. NOTE: For more information on arenas, see the malloc(3c) manpages. Table 6 lists the commands for monitoring memory-usage in an arena.
NOTE: • The info heap arenas and info heap process commands are not supported in batch mode. • The info heap process and info heap arenas are available only on HP-UX 11i v3. • The stack trace is displayed only if memory debugging is enabled. (Enable the set heap-check on command to enable memory debugging). If the stack trace is not required, the memory-usage statistics can be viewed without enabling memory checking.
bucketsize: 0 buckets: 0 retirement: 0 Exec type: SHARE_MAGIC Analyzing the info heap arenas output The info heap arenas command displays the memory-usage statistics for the specified arena. You can analyze the memory-usage statistics of all the arenas to determine if there is an imbalance in memory-usage across the arenas. For example, if there are many free blocks in an arena and these blocks are not used by threads from another arena, you can tune the memory-usage to optimize the performance.
Example 3 Monitoring memory usage in an arena Sample Program $ cat malloc_1.c 1 /* test large malloc. 2 * corruption. 3 */ 4 #include 5 #include
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 void f4_small() { char * cp; cp = malloc (60); } void set_brkpt_here() { } int main() { for (int i=0; i<777; i++) { f4_small(); f1_small(); f2_small(); f3_small(); } set_brkpt_here(); for (int i=0; i<1000; i++) { f4(); f1(); f2(); f3(); } set_brkpt_here(); } Sample Debugging Session Memory-Debugging Features of WDB 25
(gdb) -leaks malloc_1.
NOTE: WDB-GUI provides graphical representation of the Arena Profile. For more information see“Arena Profiling Using WDB GUI” (page 84). Leak Profiling The leak profile feature in WDB conservatively identifies the blocks of memory that are leaked in an application, and displays the stack trace that shows when the block was allocated. All the leaks detected by WDB are definite physical leaks. WDB uses a garbage collection algorithm to identify the blocks that are leaked.
1. Run the debugger and load the program by entering the following command: $ gdb or $ gdb –leaks 2. Enable leak checking by entering the following command: (gdb) set heap-check leaks on (if the –leaks option is not used in Step 1) NOTE: Alternatively, you can use the set heap-check on command to automatically enable the detection of leaks by toggling the set heap-check leaks on command.
Error Injection WDB supports error injection features to debug out-of-memory events in an application. It enables you to simulate out-of-memory conditions in an application and analyze the behavior of the applications under such conditions. In addition, it enables you to gain control over program execution when an out-of-memory event occurs. To simulate an out-of-memory condition, you must use the set heap-check null-check command to force malloc() to return NULL after or a random number of allocations.
Example 4 Simulating out-of-memory conditions after allocations Sample Program bash-2.05b$ cat null-check.c 1 #include 2 #include
Starting program: null Breakpoint 1, main () at null-check.c:25 25 test_null_check(); (gdb) catch nomem Catchpoint 3 (nomem) (gdb) c Continuing. warning: Malloc is returning simulated 0x00000000 value 0x70e78e8c in __rtc_nomem_event+0x4 () from /opt/langtools/lib/librtc.sl (gdb) c Continuing. Breakpoint 2, test_null_check () at null-check.c:19 19 printf("Out of memory scenario simulated\n"); (gdb) bt #0 test_null_check () at null-check.c:19 #1 0x2c70 in main () at null-check.
Example 5 Simulating out-of-memory conditions after bytes are allocated Sample Program $ cat null-check.c 1 #include 2 #include
Catchpoint 3 (nomem) (gdb) c Continuing. warning: Malloc is returning simulated 0x00000000 value 0x70e78e8c in __rtc_nomem_event+0x4() from /opt/langtools/lib/librtc.sl (gdb) c Continuing. Breakpoint 2, test_null_check () at null-check.c:19 19 printf("Out of memory scenario simulated\n"); (gdb) p i $1 = 4 (gdb) c Continuing. warning: Malloc is returning simulated 0x00000000 value 0x70e78e8c in __rtc_nomem_event+0x4 () from /opt/langtools/lib/librtc.
Example 6 Simulating out-of-memory conditions after a random number of allocations Sample Program bash-2.05b$ cat null-random.c 1 #include 2 #include 3 4 int main() 5 { 6 int i; 7 char *a; 8 for (i=0; i <= 500; i++) { 9 a = malloc(100); 10 if (a == NULL) 11 { 12 printf("Out of memory simulated\n"); 13 } 14 } 15 exit (0); 16 } Sample Debugging Session $ /opt/langtools/bin/gdb HP gdb 5.5.0 for PA-RISC 1.1 or 2.0 (narrow), HP-UX 11.00 and target hppa1.1-hp-hpux11.00.
$1 = 55 (gdb) c Continuing. Out of memory simulated warning: Malloc is returning simulated 0x00000000 value 0x70e78e8c in __rtc_nomem_event+0x4 () from /opt/langtools/lib/librtc.sl (gdb) c Continuing. Breakpoint 2, main () at null-random.c:12 12 printf("Out of memory simulated\n"); (gdb) p i $2 = 110 (gdb) c Continuing. Out of memory simulated warning: Malloc is returning simulated 0x00000000 value 0x70e78e8c in __rtc_nomem_event+0x4 () from /opt/langtools/lib/librtc.
Monitoring a Specific Address The set heap-check watch command enables you to monitor a specific address. It instructs the debugger to stop the program execution and transfer execution control to the user when the specified block at
is allocated, or de-allocated. Following is the syntax for the set heap check watch command: (gdb) set heap-check watch Example 7 (page 37) illustrates the use of the set heap-check watch command.Example 7 Monitoring a specific address Sample Program bash-2.05b$ cat watch-addr.c 1 #include 2 3 void enable_watch(char *cp) 4 { 5 6 } 7 8 int main() 9 { 10 char *cp = (char*)malloc(100); 11 enable_watch(cp); 12 free(cp); 13 exit(0); 14 } Sample Debugging Session $ /opt/langtools/bin/gdb HP gdb 5.5.0 for PA-RISC 1.1 or 2.0 (narrow), HP-UX 11.00 and target hppa1.1-hp-hpux11.00. Copyright 1986 - 2001 Free Software Foundation, Inc. Hewlett-Packard Wildebeest 5.5.
#4 0x70ee3478 in _start+0xc0 () from /usr/lib/libc.2 (gdb) c Continuing. Breakpoint 2, main () at watch-addr.c:13 13 exit(0); (gdb) q The program is running. Exit anyway? (y or n) y Monitoring Allocations Greater Than a Specified size The set heap-check block-size command instructs WDB to stop the program and transfer the execution control to the user when the program allocates a heap block whose size is greater than or equal to .
Example 8 Monitoring allocations greater than a specified size Sample Program bash-2.05b$ cat block-size.c 1 #include 2 3 int main() 4 { 5 char * cp; 6 printf("Start of the program\n"); 7 cp = (char *)malloc(1024 *1024*10); 8 free (cp); 9 exit(0); 10 } Sample Debugging Session bash-2.05b$ /opt/langtools/bin/gdb HP gdb 5.5.0 for PA-RISC 1.1 or 2.0 (narrow), HP-UX 11.00 and target hppa1.1-hp-hpux11.00. Copyright 1986 - 2001 Free Software Foundation, Inc. Hewlett-Packard Wildebeest 5.5.
size of the program by or more. Example 9 (page 41) illustrates the use of this command.
Example 9 Monitoring program heap growth Sample Program bash-2.05b$ cat heap-size.c 1 #include 2 3 int main() 4 { 5 char * cp; 6 printf("Start of the program\n"); 7 cp = (char *)malloc(1024 *1024*10); 8 free (cp); 9 cp = (char *)malloc(1024 *1024*8); 10 free (cp); 11 exit(0); 12 } Sample Debugging Session bash-2.05b$ /opt/langtools/bin/gdb HP gdb 5.5.0 for PA-RISC 1.1 or 2.0 (narrow), HP-UX 11.00 and target hppa1.1-hp-hpux11.00. Copyright 1986 - 2001 Free Software Foundation, Inc.
Monitoring Changes in Data Segment Space Allocation (High Water Mark Feature) The high water mark feature records the number of times the break value changes which is the number of times the heap grows. The high water mark feature monitors changes in the program break value. This value points to the end of the heap (which is also the end of the data segment). When memory is allocated using malloc() in excess of the available heap memory, the brk() call extends the heap. This changes the break value.
Example 10 High Water-Mark Feature Sample Program $cat high.c 1 #include 2 #include
$ gdb high HP gdb 5.6 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x. Copyright 1986 - 2001 Free Software Foundation, Inc. Hewlett-Packard Wildebeest 5.6 (based on GDB) is covered by the GNU General Public License. Type "show copying" to see the conditions to change it and/or distribute copies. Type "show warranty" for warranty/support. .. (gdb) b 40 /*set a breakpoint at the end of your application to view the highest break value for the current run*/ Breakpoint 1 at 0x4000b90:2: file high.
$ gdb high HP gdb 5.6 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x. Copyright 1986 - 2001 Free Software Foundation, Inc. Hewlett-Packard Wildebeest 5.5.8 (based on GDB) is covered by the GNU General Public License. Type "show copying" to see the conditions to change it and/or distribute copies. Type "show warranty" for warranty/support. ..
Table 11 Commands for Monitoring Heap Corruption Command Description set heap-check string Toggles validation of calls to strcpy(), strncpy(), memcpy(), memccpy(),memset(), memmove(), bzero(), and, bcopy() NOTE: HP WDB 6.0 and later versions of the debugger improves performance of memory debugging when the string option is set for 32-bit applications on HP-UX 11i v2 and later Integrity systems.
Example 11 Monitoring heap-corruption caused by erroneous handling of string functions Sample Program bash-2.05b$ cat string.c 1 #include 2 3 int main() 4 { 5 char *ptr, *ptr1; 6 7 ptr = (char*)malloc(10); 8 ptr1 = (char *)malloc(20); 9 10 strcpy(ptr, "Hello"); 11 strcpy(ptr1, "Welcome to HP WDB"); 12 13 memcpy(ptr+5,ptr1,10); 14 } Sample Debugging Session bash-2.05b$ /opt/langtools/bin/gdb string HP gdb 5.5.0 for PA-RISC 1.1 or 2.0 (narrow), HP-UX 11.00 and target hppa1.1-hp-hpux11.00.
#3 0x70e7ceb8 in memcpy+0x58 () from /opt/langtools/lib/librtc.sl #4 0x2c54 in main () at string.c:13 #5 0x70ee3478 in _start+0xc0 () from /usr/lib/libc.2 (gdb) c Continuing. Program exited normally. Detecting Out-of-Bounds Writes with the Bounds-Checking Feature The set heap-check bounds command toggles the bounds-checking feature in WDB.
Example 12 Bounds-checking to detect out-of-bounds writes Sample Program bash-2.05b$ cat bounds.c 1 #include 2 3 int main() 4 { 5 char *cp = (char*)malloc(100); 6 cp[-1] = 100; 7 strcpy(cp,"Hello"); 8 cp[100] = 100; 9 free(cp); 10 exit(0); 11 } Sample Debugging Session bash-2.05b$ gdb bounds HP gdb 5.5.0 for PA-RISC 1.1 or 2.0 (narrow), HP-UX 11.00 and target hppa1.1-hp-hpux11.00. Copyright 1986 - 2001 Free Software Foundation, Inc. Hewlett-Packard Wildebeest 5.5.
(gdb) c Continuing. warning: Memory block (size = 100 address = 0x4042a3c8) appears to be corrupted at the end. Allocation context not found #1 main() at bounds.c:5 #2 _start() from /usr/lib/libc.2 #3 _start() from /opt/langtools/lib/librtc.sl #4 $START$() from warning: Use command backtrace (bt) to see the current context. Ignore top 4 frames belonging to leak detection library of gdb. 0x70e78d7c in __rtc_event+0 () from /opt/langtools/lib/librtc.sl (gdb) f 4 #4 0x4000960:0 in main () at bounds.
command. The corruption information is written to a specified file if the is provided. Otherwise, it is written to stdout. In addition, it lists the in-block corruptions in the freed blocks if the set heap-check retain-freed-blocks is set to on. NOTE: The info corruption command is not supported in batch mode debugging Example 13 (page 52) illustrates the use of the info corruption command.
Example 13 Detecting heap corruption using the info corruption command Sample Program $cat infobounds.c 1 #include 2 #include
(gdb) run Starting program: infobounds Breakpoint 1, main () at .infobounds.c:25 25 printf("Hello\n"); (gdb) info corruption Analyzing heap ... Following blocks appear to be corrupted No. Total bytes Blocks Address Function 0 10 1 0x400124e0 sm_malloc() 1 10 1 0x40012500 sm_malloc() 2 10 1 0x40012520 sm_malloc() (gdb) info corruption 2 10 bytes at 0x40012520 (33.33% of all bytes allocated) #0 sm_malloc() at infobounds.c:12 #1 main() at infobounds.c:21 #2 main_opd_entry() from /usr/lib/hpux32/dld.
NOTE: Software literature names this concept as premature free or Reading/writing freed memory using a pointer. WDB tracks the dangling pointers and dangling blocks using a modified version of Garbage collection. The enabler for doing this is by retaining all the freed blocks internally within RTC without actually freeing it as long as possible. It displays all the potential pointers to the freed dangling blocks, in the application data space.
Example 14 Scrambling a memory block on de-allocation Sample Program $ cat scramble.c 1 #include 2 #include 3 4 int 5 main () 6 { 7 char **tp; 8 tp = malloc (100); 9 printf ("Batch RTC test over, *tp=%p.\n", *tp); 10 fflush(stdout); 11 free(tp); 12 exit (0); 13 } Sample Debugging Session $ gdb scramble HP gdb 5.5 for PA-RISC 1.1 or 2.0 (narrow), HP-UX 11.00 and target hppa1.1-hp-hpux11.00. Copyright 1986 - 2001 Free Software Foundation, Inc. Hewlett-Packard Wildebeest 5.5.
NOTE: This feature is currently supported only for batch-mode of memory debugging on HP Integrity systems. Currently, only the files opened/closed using the following library calls are monitored: • open() • close() • creat() • dup() • dup2() • fopen() • fclose() • freopen() • fcntl() Table 12 Command for Reporting Open Files 56 Command Description check_openfd=[on|off] Enable/Disable the detection of open file descriptors.
Example 15 A sample c program and its openfd report obtained using wdb batch mode Sample Program 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include #include #include
------------------------------------------------------------------------File Name : File Descriptor : 1 File Type : Character device ------------------------------------------------------------------------File Name : File Descriptor : 2 File Type : Character device ------------------------------------------------------------------------File Name : /tmp/textfile File Descriptor : 4 File Type : Regular type Stack-trace :#0 func()() at do_fopen.c:23 #1 main() at do_fopen.
Table 13 Options for Performance Improvement Setting Command Description Stack Depth set heap-check frame-count Controls the depth of the call stack. By default, num is set to 4. Minimum Leak Size set heap-check min-leak-size Specifies the minimum leak size for stack trace collection. The debugger continues to report leaks that are smaller than bytes, but it does not provide the stack trace for the same. By default, num is set to 0.
3. Place breakpoints at probe points by entering the following command: (gdb)b 4. To generate a leak profile at the breakpoint, enter the following command: (gdb)info leaks 5. To generate a snapshot heap profile at the breakpoint, enter the following command: (gdb) info heap Debugging in Batch Mode In this mode, the user does not interactively issue commands in a debugger session.
Pre-loading the Appropriate Version of librtc.[sl|so] Along With the Application The appropriate version of the librtc.[sl|so] runtime library must be preloaded to enable batch mode and attach mode memory debugging of an application. You can explicitly preload librtc.[sl|so] from the appropriate path by using the LD_PRELOAD environment variable. Alternately you can use the +rtc option for the chatr command to automatically preload librtc.[sl|so].
NOTE: To preload from a path that is different from the default paths, you must use the LD_PRELOAD environment variable. Using LD_PRELOAD TO Preload librtc.[sl|so] To explicitly preload an appropriate version of librtc.[sl|so] with the application, set the environment variable, LD_PRELOAD as follows: • For 32-bit applications running on Itanium, LD_PRELOAD=/opt/langtools/lib/hpux32/librtc.
NOTE: On Itanium systems, librtc versions prior to 6.1, the Batch Mode RTC displays one of the following errors and causes the program to temporarily hang if the version of GDB and librtc.[sl|so] do not match, or if GDB is not available on the system: /opt/langtools/bin/gdb: unrecognized option ‘-brtc’ Use ‘/opt/langtools/bin/gdb --help’ for a complete list of options. (OR) execl failed. Cannot print RTC info: No such file or directory This error does not occur under normal usage where GDB or librtc.
configuration file by exporting the environment variable GDBRTC_CONFIG to contain the pathname of the configuration file (including the filename.) The following example illustrates how to specify the path of the configuration file: $ export GDBRTC_CONFIG=/tmp/rtcconfig If the path to the configuration file is not specified, the debugger assumes that the rtcconfig configuration file, by default, is located in the current working directory.
NOTE: It is incorrect to use spaces before or after the ’=’ symbol in the batch mode configuration options in the configuration file, rtcconfig. Additionally, it is incorrect to use spaces before the batch mode configuration options.
Table 15 The config_strings Options for RTC_MALLOC_CONFIG config_string Options Description abort_on_bounds=[01] RTC_NO_ABORT must not be set. If abort_on_bounds is set to 1, the batch mode aborts execution of the program and reports the bounds condition, when bound checking fails. abort_on_bad_free=[01] RTC_NO_ABORT must not be set. If abort_on_bad_free is set to 1, the batch mode aborts execution when a free(), or a realloc() call attempts to free a heap object that is not valid.
Debugging in Batch Mode To debug an application in the batch mode, complete the following steps: 1. Compile the source files. NOTE: On HP 9000 systems, you must map the shared libraries as private, by using the chatr command if you are using LD_PRELOAD to preload the librtc.[sl|so] instead of the +rtc option for the chatr command . chatr +dbg enable .
4. You can use the +rtc option for the chatr command to automatically preload librtc.[sl|so] or you can explicitly preload librtc.[sl|so] from the appropriate path by using the LD_PRELOAD environment variable. NOTE: The +mem_check option for the chatr command is available for dynamic linker versions B.11.61 and later on HP 9000 systems, and dynamic linker versions B.12.46 and later on Integrity systems.
Following is the syntax for using LD_PRELOAD_ONCE: LD_PRELOAD_ONCE= /opt/langtools/lib/librtc.sl Example 16 (page 70) illustrates the batch mode debugging of the memtest.c program. The debugging results are stored in memtest.8494.mem, memtest.8494.heap, and memtest.8494.leaks.
Example 16 Batch Mode Debugging for a 32-bit Application running on Itanium Sample Program $ cat memtest.c 1 #include 2 #include 3 #include 4 5 #include
$ cat memtest.8494.mem ----------------------------------------Attempt to free unallocated or already freed object at 0x4006e7b0 (0) 0x60000000cac1bdc0 print_stack_trace_to_log_file + 0x1d0 at ../../../Src/gnu/gdb/infrtc.c:996 [/opt/langtools/lib/hpux32/librtc.sl] (1) 0x60000000cac1d3e0 __rtc_event + 0x160 at ../../../Src/gnu/gdb/infrtc.c:1296 [/opt/langtools/lib/hpux32/librtc.sl] (2) 0x60000000cac22da0 rtc_record_free + 0x380 at ../../../Src/gnu/gdb/infrtc.c:2651 [/opt/langtools/lib/hpux32/librtc.
#1 main_opd_entry() from /usr/lib/hpux32/dld.so ------------------------------------------------------------ Debugging Multiple Applications in Batch Mode To debug multiple applications in the batch mode, complete the following steps: 1. 2. Compile the source files. Set the required variables in the rtcconfig configuration file, as follows: $ cat rtcconfig "rtcconfig" 5 lines, 83 characters set heap-check on set heap-check free on files=exec1:exec2:exec3 output_dir= ./ 3.
4. Complete one of the following steps to preload librtc.[sl|so]: • Use the +rtc option for the chatr command on each of the required executable files that must be instrumented, as follows: $ chatr +rtc enable exec1 exec2 exec3 The +rtc option for the chatr command is available for dynamic linker versions B.11.66 and later on HP 9000 systems, and dynamic linker versions B.12.51 and later on Integrity systems. (Or) • Preload librtc.
1. You can use the +rtc option for the chatr command to automatically preload librtc.[sl|so] or you can explicitly preload librtc.[sl|so] from the appropriate path by using the LD_PRELOAD environment variable. To preload the librtc.[sl|so] runtime library, complete one of the following steps: • To automatically preload librtc.
NOTE: To attach and find leaks for PA-32 applications from the startup, the environment variable RTC_INIT must be set to on in addition to preloading the librtc.[sl|so] library before starting the application, as follows: $ LD_PRELOAD=/opt/langtools/lib/librtc.sl RTC_INIT=on If RTC_INIT is enabled, librtc.[sl|so] starts recording heap information for PA32 process by default. Hence, you must set this environment variable only when it is required.
Table 16 Commonly Used Commands for Memory Debugging (continued) Description Interactive Mode/Attach Mode Batch Mode Enables you to set the minimum block size to use for leak detection.
Table 16 Commonly Used Commands for Memory Debugging (continued) Description Interactive Mode/Attach Mode Batch Mode Starts the incremental heap growth set heap-check interval profile. All allocations prior to the execution of this command are ignored. If incremental heap growth profile is already on, executing this command resets the counters and starts a fresh collection. The interval is specified in seconds.
Table 16 Commonly Used Commands for Memory Debugging (continued) Description Interactive Mode/Attach Mode Batch Mode Enables you to stop whenever compiler detects corruption in variables allocated by compiler. The application should be compiled with +check=all option. set heap-check compiler Not supported in Batch Mode Enables you to detect open file descriptors.
1. 2. 3. 4. Load the program to WDB as follows: • Select File —> Load Program in the WDB GUI window. • In the Load Program dialog-box, enter the executable name to load the executable or use the PID to attach a process for debugging. After you load the application, you can set the memory checking preferences by setting the preferences in the Memory Checking window. Select Tools —>Memory Checking to activate the Memory Checking window.
6. 7. Select View->Memory Usage->Incremental Heap to view the incremental heap profile. The Incremental Heap View window displays the incremental heap profile graph for the program The incremental heap profile graph can be plotted based on the outstanding allocations in the program or the actual heap profile, as follows: • To view the incremental heap profile graph based on the outstanding allocations, select the Allocation option in the Plot Graph frame.
Figure 1 Allocation Profile Debugging Memory Using WDB GUI 81
Figure 2 Heap Space Profile Debugging Memory Using WDB GUI 83
Figure 3 Incremental Heap Profile Summary Arena Profiling Using WDB GUI HP WDB GUI 5.7 and later versions provide support to view the arena information for a program running on HP-UX 11i v3. To view the arena information, complete the following steps: 1. 2. 3. Load the program to HP WDB GUI. Stop the program execution at the required breakpoints. Select View->Memory Usage->Heap Arena to view the arena information. The arena information is displayed in the View Heap Arena window.
The Arenas Block Distribution window displays the block level space distribution graph for an arena. The graph displays the space occupied by the user blocks, the free blocks, the unclaimed space, and the malloc metadata (which includes the node blocks, the cached blocks, the holding header blocks, and the holding SBA blocks). The virtual address of the blocks is used to arrange the blocks in the graph.
The number of blocks occupied by the used ordinary blocks, the used small blocks, the free ordinary blocks, and the free small blocks across the arenas are displayed in a pie chart. This information is also displayed in a table.
Figure 5 View Heap Arena Window 2 Debugging Memory Using WDB GUI 87
Figure 6 Arena Summary Figure 7 Arena Block Distribution 88
Step by Step Approach for Detecting Leaks This section provides the guidelines and a sample test case to enable you detect memory leaks by going through a step by step procedure. Steps to Detect Point of Memory Leak To detect the point of memory leak, ensure that you go through following steps: 1. 2. 3. Enable memory leak detection for the application run and collect the leak report in batch mode. To enable leak detection, use check_leaks=on in the rtcconfig file.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 90 printf("No memory available, aborting...\n"); abort (); } return memBlock; } /* Create a header string and return to the caller */ char *createHeader() { char *headerString = (char *) allocateMemory(20); strcpy (headerString, "Header : My string "); return headerString; } /* Create a string with header and input.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 { printf("Enter length of string 1\n"); scanf("%d", & s1length); str1 = createString("String 1", s1length); } while (str1 == NULL); /* Allocate second string and initialize it */ do { printf("Enter length of string 2\n"); scanf("%d", & s2length); str2 = createString("String 2", s2length); } while (str2 == NULL); /* Compare strings */ if (strcmp(str1, str2)) { printf("str1 > str2 \n"); } else { pri
Example 17 Collecting memory leak report using batch mode To collect the memory leak report using batch mode, complete the following steps: a. Compile the source file. $ aCC -Ae -o memLeak -g memLeak.c b. Set the target application to preload the librtc runtime library, enter the following command at the HP-UX prompt: $ chatr +rtc enable memLeak c. Set an environment variable BATCH_RTC. If you are using the Korn or Posix shell, enter the following command at the HP-UX prompt: $ export BATCH_RTC=on d.
Detailed Report ------------------------------------------------------------------------20 bytes leaked at 0x40061a00 (100.00% of all bytes leaked) #0 0x04000d62 allocateMemory() at memLeak.c:11 #1 0x04000e62 createHeader() at memLeak.c:24 #2 0x04000f32 createString() at memLeak.c:37 #3 0x040012b2 compareStrings() at memLeak.c:74 After knowing the memory leak information in the application through batch mode, select the leaks one by one and follow the procedure mentioned below. 2.
Example 18 Detecting the location of memory leak To detect the location of the first leak, follow the steps mentioned below: a. Execute the program under gdb with memory leak detection option using the command shown below: $ gdb -leaks memLeak HP gdb 6.0.3 for HP Itanium (32 or 64 bit) and target HP-UX 11iv2 and 11iv3. Copyright 1986 - 2009 Free Software Foundation, Inc. Hewlett-Packard Wildebeest 6.0.3 (based on GDB) is covered by the GNU General Public License.
d. Step into the next calling function i.e. the createString() and collect leak information with the info leaks command when the execution reaches there. NOTE: The leak information is not shown as the hdrString is pointing to the allocated memory of size 20. (gdb) finish Run till exit from #0 0x4000e70:0 in createHeader () at memLeak.c:24 0x4000f40:0 in createString (input=0x4000bc0 "String 1", n=25) at memLeak.
memory analysis tool. WDB enables you to debug memory leaks and heap-related errors in an application. In addition to plugging memory leaks in your application, it is also important to track the memory utilization in your application. WDB provides capabilities such as heap profiling and error injection to analyze the memory-usage of your application. The heap profile displays information about the allocated memory, the calling function, and it also displays the allocating call stack.
Example 19 Detecting a double free error Sample Program $ cat double-free.c #include 1 2 int main() 3 { 4 5 printf("Starting program\n"); 6 char* han = (char*)malloc(sizeof(char)); 7 free(han); 8 printf("Now freeing a pointer twice...\n"); 9 free(han); 10 } Sample Debugging Session (gdb) set heap-check free on (gdb) file double-free Reading symbols from double-free...done. (gdb) b main Breakpoint 1 at 0x2be4: file double-free.c, line 5 from double-free.
Example 20 Detecting de-allocation of memory that has not been initialized Sample Program $ 1 2 3 4 5 6 7 8 cat unalloc.c #include int main() { printf("Starting program\n"); char* han; free(han); } Sample Debugging Session gdb) set heap-check on (gdb) file unalloc Reading symbols from unalloc...done. (gdb) b main Breakpoint 1 at 0x2bb4: file unalloc.c, line 5 from unalloc. (gdb) r Starting program: unalloc Breakpoint 1, main () at unalloc.
Example 21 Detecting de-allocation of un-allocated blocks Sample Program $ 1 2 3 4 5 6 7 8 9 cat unit.c #include int main() { printf("Starting program\n"); int *han = (int*)malloc(sizeof(int)); han++; free(han); } Sample Debugging Session (gdb) set heap-check on (gdb) file uninit Reading symbols from uninit...done. (gdb) b main Breakpoint 1 at 0x2bdc: file uninit.c, line 5 from uninit. (gdb) r Starting program: uninit Breakpoint 1, main () at uninit.
Example 22 Detecting memory leaks that are caused when an application overwrites a pointer that currently addresses a block of memory with another address or data Sample Program $ cat memleak1.c 1 #include 2 3 int main() { 4 5 printf("Starting program\n"); 6 int* han1 = (int*)malloc(sizeof(int)); 7 int* han2 = (int*)malloc(sizeof(int)); 8 han1 = han2; 9 free(han1); 10 } Sample Debugging Session (gdb) set heap-check on (gdb) file memleak1 Reading symbols from memleak1...done.
#3 $START$() from Additional Examples 101
Example 23 Detecting memory leaks that are caused when a pointer variable in an application addresses memory that is out of the scope of the application Sample Program $ cat memleak2.c 1 #include
#2 #3 main() at memleak2.c:17 _start() from /usr/lib/libc.
Example 24 Detecting memory leaks when you free a structure or an array that has pointers which are not freed. Sample Program $ cat memleak3.c 1 #include 2 3 struct stud 4 { 5 char* name; 6 int id; 7 }; 8 9 int main() { 10 11 struct stud *s1; 12 s1 = (struct stud*)malloc(sizeof(struct stud)); 13 s1->name = (char*)malloc(50); 14 strcpy(s1->name,"Annie"); 15 s1->id=10; 16 free(s1); 17 } Sample Debugging Session (gdb) set heap-check on (gdb) file memleak3 Reading symbols from memleak3...done.
Example 25 Work-Around when program execution is in a frame that belongs to the GDB internal leak detection library ... (gdb) set heap-check on (gdb) r Starting program: corruption warning: Memory block (size = 80 address = 0x40453970) appears to be corrupted at the end. Allocation context not found #1 main() at corruption.c:4 #2 main_opd_entry() from warning: Use command backtrace (bt) to see the current context. Ignore top 4 frames belonging to leak detection library of gdb. __rtc_event () at ../../..
4 5 Yes. WDB supports detection of leaks in a third party code also. What are the commands that the batch mode of memory-debugging does not support? For more information on the commands that are supported in batch mode, see “Summary of Memory Debugging Commands” (page 75) Can WDB debug applications with user-defined memory management routines? WDB can debug applications with memory management routines that are either user defined or are wrappers to the default memory management routines.
In the case of Itanium binaries, and PA—RISC 64–bit binaries, the debugger finds leaks in the executable from the startup of the executable by default, when debugging in attach mode. However, to find leaks in the executable from the startup of PA-RISC 32–bit binaries in the attach mode, the environment variable RTC_INIT must be set to on in addition to preloading the librtc.[sl|so] library before starting the application, as follows: $ LD_PRELOAD=/opt/langtools/lib/librtc.
The batch mode RTC might have problems if the application has atfork handler. This issue has been resolved from version 6.1 of librtc on Itanium systems.
Monitoring Heap Events, 35 P Prerequisites for Memory Debugging, 7 R RTC_MALLOC_CONFIG, 65 S set heap-check block-size , 38 set heap-check bounds , 48 set heap-check frame-count , 58 set heap-check free , 45 set heap-check heap-size , 39 set heap-check high-mem-count , 42 set heap-check interval, 16 set heap-check leaks , 27 set heap-check min-leak-size , 58 set heap-check null-check , 29 set heap-check null-check null-check-size ,