Skip Navigation Links | |
Exit Print View | |
Oracle Solaris Studio 12.3: Discover and Uncover User's Guide Oracle Solaris Studio 12.3 Information Library |
2. Memory Error Discovery Tool (Discover)
Requirements for Using Discover
Binaries Must Be Prepared Correctly
Binaries That Use Preloading or Auditing Cannot Be Used
Binaries That Redefine Standard Memory Allocation Functions Can Be Used
Instrumenting a Prepared Binary
Instrumenting Shared Libraries
SUNW_DISCOVER_OPTIONS Environment Variable
SUNW_DISCOVER_FOLLOW_FORK_MODE Environment Variable
Running an Instrumented Binary
Memory Access Errors and Warnings
Interpreting Discover Error Messages
Limitations When Using Discover
Only Annotated Code is Instrumented
Machine Instruction Might Differ From Source Code
Compiler Options Affect the Generated Code
System Libraries Can Affect the Errors Reported
Custom Memory Management Can Affect the Accuracy of the Data
Out of Bounds Errors for Static and Automatic Arrays Cannot Be Detected
The Discover report provides you with information to effectively pinpoint and fix the problems in your source code.
By default, the report is written in HTML format to output_file.html, where output_file is the basename of the instrumented binary. The file is placed in the working directory where you run the instrumented binary.
When you instrument your binary, you can use the -H option to request that the HTML output be written to a specified file, or the -w option to request that it be written to a text file (see Command Line Options).
After your binary is instrumented, you can change the settings of the -H and -w options for the report in the SUNW_DISCOVER_OPTIONS Environment Variable if, for example, you want to write the report to a different file for a subsequent run of the program.
The HTML report format allows interactive analysis of your program. The data in HTML format can easily be shared between developers using email or placement on a web page. Combined with JavaScript interactive features, it provides a convenient way to navigate through the Discover messages.
The Errors tab (see Using the Errors Tab), Warnings tab (see Using the Warnings Tab, and Memory Leaks tab (see Using the Memory Leaks Tab) let you navigate through error messages, warning messages, and the memory leak report, respectively.
The control panel on the left (see Using the Control Panel) lets you change the contents of the tab that is currently displayed on the right.
When you first open an HTML report in your browser, the Errors tab is selected and displays the list of memory access errors that occurred during execution of your instrumented binary.
When you click on an error, the stack trace at the time of the error is displayed:
If you compiled your code with the -g option, you can see the source code for each function in the stack trace by clicking the function:
The Warnings tab displays all of the warning messages for possible access errors. When you click on a warning, the stack trace at the time of the warning is displayed. If you compiled your code with the -g option, you can see the source code for each function in the stack trace by clicking the function.
The Memory Leaks tab displays the total number of blocks remaining allocated at the end of the program's run at the top, with the blocks listed below.
When you click on a block, the stack trace for the block is displayed. If you compiled your code with the -g option, you can see the source code for each function in the stack trace by clicking the function.
To see the stack traces for all of the errors, warnings, and memory leaks, click Expand All in the Stack Traces section of the control panel. To see the source code for all of the functions, click Expand All in the Source Code section of the control panel.
To hide the stack traces or source code for all of the errors, warnings, and memory leaks, click the corresponding Collapse All.
The Show Errors section of the control panel is displayed when the Errors tab is selected and lets you control which types of errors are displayed. By default, the checkboxes for all of the detected errors are checked. To hide a type of error, click its checkbox to remove the checkmark.
The Show Warnings section of the control panel is displayed when the Warnings tab is selected and lets you control which types of warnings are displayed. By default, the checkboxes for all of the detected warnings are checked. To hide a type of warning, click its checkbox to remove the checkmark.
A summary of the report listing the total numbers of errors and warnings, and the amount of leaked memory, is displayed at the bottom of the control panel.
The ASCII (text) format of the Discover report is suitable for processing by scripts or when you don't have access to a web browser. The following is an example of an ASCII report.
$ a.out ERROR 1 (UAW): writing to unallocated memory at address 0x50088 (4 bytes) at: main() + 0x2a0 <ui.c:20> 17: t = malloc(32); 18: printf("hello\n"); 19: for (int i=0; i<100;i++) 20:=> t[32] = 234; // UAW 21: printf("%d\n", t[2]); //UMR 22: foo(); 23: bar(); _start() + 0x108 ERROR 2 (UMR): accessing uninitialized data from address 0x50010 (4 bytes) at: main() + 0x16c <ui.c:21>$ 18: printf("hello\n"); 19: for (int i=0; i<100;i++) 20: t[32] = 234; // UAW 21:=> printf("%d\n", t[2]); //UMR 22: foo(); 23: bar(); 24: } _start() + 0x108 was allocated at (32 bytes): main() + 0x24 <ui.c:17> 14: x = (int*)malloc(size); // AZS warning 15: } 16: int main() { 17:=> t = malloc(32); 18: printf("hello\n"); 19: for (int i=0; i<100;i++) 20: t[32] = 234; // UAW _start() + 0x108 0 WARNING 1 (AZS): allocating zero size memory block at: foo() + 0xf4 <ui.c:14> 11: void foo() { 12: x = malloc(128); 13: free(x); 14:=> x = (int*)malloc(size); // AZS warning 15: } 16: int main() { 17: t = malloc(32); main() + 0x18c <ui.c:22> 19: for (int i=0; i<100;i++) 20: t[32] = 234; // UAW 21: printf("%d\n", t[2]); //UMR 22:=> foo(); 23: bar(); 24: } _start() + 0x108 ***************** Discover Memory Report ***************** 1 block at 1 location left allocated on heap with a total size of 128 bytes 1 block with total size of 128 bytes bar() + 0x24 <ui.c:9> 6: 7: void bar() { 8: int *y; 9:=> y = malloc(128); // Memory leak 10: } 11: void foo() { 12: x = malloc(128); main() + 0x194 <ui.c:23> 20: t[32] = 234; // UAW 21: printf("%d\n", t[2]); //UMR 22: foo(); 23:=> bar(); 24: } _start() + 0x108 ERROR 1: repeats 100 times DISCOVER SUMMARY: unique errors : 2 (101 total, 0 filtered) unique warnings : 1 (1 total, 0 filtered)
The report consists of error and warning messages followed by a summary.
The error message starts with the word ERROR and contains a three-letter code, an id number, and an error description (writing to unallocated memory in the example). Other details include the memory address that was accessed and the number or bytes read or written. Following the description is a stack trace at the time of the error that pinpoints the location of the error in the process life cycle.
If the program was compiled with the -g option, the stack trace includes the source file name and line number. If the source file is accessible, the source code in the vicinity of the error is printed. The target source line in each frame is indicated by the => symbol.
When the same kind of error at the same memory location with the same number of bytes repeats, the complete message including the stack trace is printed only once. Subsequent occurrences of the error are counted and a repetition count, as shown in the following example, is listed at the end of the report for each identical error that occurs multiple times.
ERROR 1: repeats 100 times
If the address of the faulty memory access is on the heap, then information on the corresponding heap block is printed after the stack trace. The information includes the block starting address and size, and a stack trace at the time the block was allocated. If the block was freed, a stack trace of the deallocation point is also included.
Warning messages are printed in the same format as error messages except that they start with the word WARNING. In general, these messages alert you to conditions that do not affect application correctness, but provide useful information that you can use to improve the program. For example, allocating memory of zero size is not harmful, but if it happens too often, it can potentially degrade performance.
The memory leak report contains information about memory blocks allocated on the heap but not released at program exit. The following is an example of a memory leak report.
$ DISCOVER_MEMORY_LEAKS=1 ./a.out ... ***************** Discover Memory Report ***************** 2 blocks left allocated on heap with total size of 44 bytes block at 0x50008 (40 bytes long) was allocated at: malloc() + 0x168 [libdiscover.so:0xea54] f() + 0x1c [a.out:0x3001c] <discover_example.c:9>: 8: { 9:=> int *a = (int *)malloc( n * sizeof(int) ); 10: int i, j, k; main() + 0x1c [a.out:0x304a8] <discover_example.c:33>: 32: /* Print first N=10 Fibonacci numbers */ 33:=> a = f(N); 34: printf("First %d Fibonacci numbers:\n", N); _start() + 0x5c [a.out:0x105a8] ...
The first line following the header summarizes the number of heap blocks left allocated on the heap and their total size. The reported size is from the developer's perspective, that is, it does not include the bookkeeping overhead of the memory allocator.
After the memory leak summary, detailed information is printed on each unfreed heap block with a stack trace of its allocation point. The stack trace report is similar to the one described for error and warning messages.
The Discover report is concluded with an overall summary. It reports the number of unique warnings and errors and in parentheses, the total numbers of errors and warnings, including repeated ones. For example:
DISCOVER SUMMARY: unique errors : 3 (3 total) unique warnings : 1 (5 total)