Skip Navigation Links | |
Exit Print View | |
Oracle Solaris Studio 12.3: Debugging a Program With dbx Oracle Solaris Studio 12.3 Information Library |
4. Viewing and Navigating To Code
5. Controlling Program Execution
6. Setting Breakpoints and Traces
8. Evaluating and Displaying Data
Capabilities of Runtime Checking
Turning On Memory Use and Memory Leak Checking
Turning On Memory Access Checking
Turning On All Runtime Checking
Understanding the Memory Access Error Report
Limiting the Number of Errors Reported
Using Suppression to Manage Errors
Using Runtime Checking on a Child Process
Using Runtime Checking on an Attached Process
Using Fix and Continue With Runtime Checking
Runtime Checking Application Programming Interface
Using Runtime Checking in Batch Mode
Enabling Batch Mode Directly From dbx
Works Better With More Symbols and Debug Information
SIGSEGV and SIGALTSTACK Signals Are Restricted on x86 Platforms
Read From Array Out-of-Bounds (rob) Error
Read From Unallocated Memory (rua) Error
Read From Uninitialized Memory (rui) Error
Write to Array Out-of-Bounds Memory (wob) Error
Write to Read-Only Memory (wro) Error
Write to Unallocated Memory (wua) Error
Address in Register (air) Error
11. Debugging Multithreaded Applications
16. Debugging Fortran Using dbx
17. Debugging a Java Application With dbx
18. Debugging at the Machine-Instruction Level
19. Using dbx With the Korn Shell
A memory leak is a dynamically allocated block of memory that has no pointers pointing to it anywhere in the data space of the program. Such blocks are orphaned memory. Because there are no pointers pointing to the blocks, programs cannot reference them, much less free them. Runtime checking finds and reports such blocks.
Memory leaks result in increased virtual memory consumption and generally result in memory fragmentation. This might slow down the performance of your program and the whole system.
Typically, memory leaks occur because allocated memory is not freed and you lose a pointer to the allocated block. Here are some examples of memory leaks:
void foo() { char *s; s = (char *) malloc(32); strcpy(s, "hello world"); return; /* no free of s. Once foo returns, there is no */ /* pointer pointing to the malloc’ed block, */ /* so that block is leaked. */ }
A leak can result from incorrect use of an API.
void printcwd() { printf("cwd = %s\n", getcwd(NULL, MAXPATHLEN)); return; /* libc function getcwd() returns a pointer to */ /* malloc’ed area when the first argument is NULL, */ /* program should remember to free this. In this */ /* case the block is not freed and results in leak.*/ }
You can avoid memory leaks by always freeing memory when it is no longer needed and paying close attention to library functions that return allocated memory. If you use such functions, remember to free up the memory appropriately.
Sometimes the term memory leak is used to refer to any block that has not been freed. This is a much less useful definition of a memory leak, because it is a common programming practice not to free memory if the program will terminate shortly. Runtime checking does not report a block as a leak, if the program still retains one or more pointers to it.
Runtime checking detects the following memory leak errors:
mel (see Memory Leak (mel) Error)
air (see Address in Register (air) Error)
aib (see Address in Block (aib) Error)
Note - Runtime checking only finds leaks of malloc memory. If your program does not use malloc, runtime checking cannot find memory leaks.
There are two cases where runtime checking can report a “possible” leak. The first case is when no pointers are found pointing to the beginning of the block, but a pointer is found pointing to the interior of the block. This case is reported as an “Address in Block (aib)” error. If it was a stray pointer that pointed into the block, this would be a real memory leak. However, some programs deliberately move the only pointer to an array back and forth as needed to access its entries. In this case, it would not be a memory leak. Because runtime checking cannot distinguish between these two cases, it reports both of them as possible leaks, letting you determine which are real memory leaks.
The second type of possible leak occurs when no pointers to a block are found in the data space, but a pointer is found in a register. This case is reported as an “Address in Register (air)” error. If the register points to the block accidentally, or if it is an old copy of a memory pointer that has since been lost, then this is a real leak. However, the compiler can optimize references and place the only pointer to a block in a register without ever writing the pointer to memory. Such a case would not be a real leak. Hence, if the program has been optimized and the report was the result of the showleaks command, it is likely not to be a real leak. In all other cases, it is likely to be a real leak. For more information, see showleaks Command.
Note - Runtime leak checking requires the use of the standard libc malloc/free/realloc functions or allocators based on those functions. For other allocators, see Runtime Checking Application Programming Interface .
If memory leak checking is turned on, a scan for memory leaks is automatically performed just before the program being tested exits. Any detected leaks are reported. The program should not be killed with the kill command. Here is a typical memory leak error message:
Memory leak (mel): Found leaked block of size 6 at address 0x21718 At time of allocation, the call stack was: [1] foo() at line 63 in test.c [2] main() at line 47 in test.c
A UNIX program has a main procedure (called MAIN in f77) that is the top-level user function for the program. Normally, a program terminates either by calling exit(3) or by returning from main. In the latter case, all variables local to main go out of scope after the return, and any heap blocks they pointed to are reported as leaks (unless global variables point to those same blocks).
It is a common programming practice not to free heap blocks allocated to local variables in main, because the program is about to terminate and return from main without calling exit(). To prevent runtime checking from reporting such blocks as memory leaks, stop the program just before main returns by setting a breakpoint on the last executable source line in main. When the program halts there, use the showleaks command to report all the true leaks, omitting the leaks that would result merely from variables in main going out of scope.
For more information, see showleaks Command.
With leak checking turned on, you receive an automatic leak report when the program exits. All possible leaks are reported, provided the program has not been killed using the kill command. The level of detail in the report is controlled by the dbx environment variable rtc_mel_at_exit (see Setting dbx Environment Variables). By default, a nonverbose leak report is generated.
Reports are sorted according to the combined size of the leaks. Actual memory leaks are reported first, followed by possible leaks. The verbose report contains detailed stack trace information, including line numbers and source files whenever they are available.
Both reports include the following information for memory leak errors:
|
Here is the corresponding nonverbose memory leak report.
Actual leaks report (actual leaks: 3 total size: 2427 bytes) Total Num of Leaked Allocation call stack Size Blocks Block Address ========== ====== ========== ======================================= 1852 2 - true_leak < true_leak 575 1 0x22150 true_leak < main Possible leaks report (possible leaks: 1 total size: 8 bytes) Total Num of Leaked Allocation call stack Size Blocks Block Address ========== ====== ========== ======================================= 8 1 0x219b0 in_block < main
Following is a typical verbose leak report.
Actual leaks report (actual leaks: 3 total size: 2427 bytes) Memory Leak (mel): Found 2 leaked blocks with total size 1852 bytes At time of each allocation, the call stack was: [1] true_leak() at line 220 in "leaks.c" [2] true_leak() at line 224 in "leaks.c" Memory Leak (mel): Found leaked block of size 575 bytes at address 0x22150 At time of allocation, the call stack was: [1] true_leak() at line 220 in "leaks.c" [2] main() at line 87 in "leaks.c" Possible leaks report (possible leaks: 1 total size: 8 bytes) Possible memory leak -- address in block (aib): Found leaked block of size 8 bytes at address 0x219b0 At time of allocation, the call stack was: [1] in_block() at line 177 in "leaks.c" [2] main() at line 100 in "leaks.c"
You can ask for a leak report at any time using the showleaks command, which reports new memory leaks since the last showleaks command. For more information, see showleaks Command.
Because the number of individual leaks can be very large, runtime checking automatically combines leaks allocated at the same place into a single combined leak report. The decision to combine leaks, or report them individually, is controlled by the number-of-frames-to-match parameter specified by the -match m option on a check -leaks or the -m option of the showleaks command. If the call stack at the time of allocation for two or more leaks matches to m frames to the exact program counter level, these leaks are reported in a single combined leak report.
Consider the following three call sequences:
|
If all of these blocks lead to memory leaks, the value of m determines whether the leaks are reported as separate leaks or as one repeated leak. If m is 2, Blocks 1 and 2 are reported as one repeated leak because the 2 stack frames above malloc() are common to both call sequences. Block 3 will be reported as a separate leak because the trace for c() does not match the other blocks. For m greater than 2, runtime checking reports all leaks as separate leaks. (The malloc is not shown on the leak report.)
In general, the smaller the value of m, the fewer individual leak reports and the more combined leak reports are generated. The greater the value of m, the fewer combined leak reports and the more individual leak reports are generated.
Once you have obtained a memory leak report, follow these guidelines for fixing the memory leaks.
Most importantly, determine where the leak is. The leak report tells you the allocation trace of the leaked block, the place where the leaked block was allocated.
You can then look at the execution flow of your program and see how the block was used. If it is obvious where the pointer was lost, the job is easy; otherwise you can use showleaks to narrow your leak window. By default the showleaks command gives you the new leaks created only since the last showleaks command. You can run showleaks repeatedly while stepping through your program to narrow the window where the block was leaked.
For more information, see showleaks Command.