First, a reminder - Oracle Solaris Studio 12.4 is now generally available. Check the Solaris Studio 12.4 Data Sheet before downloading the software from Oracle Technology Network.
Dynamic Memory Usage Analysis
Code Analyzer tool in Oracle Solaris Studio compiler suite can analyze static data, dynamic memory access data, and code coverage data collected from binaries that were compiled with the C/C++ compilers in Solaris Studio 12.3 or later. Code Analyzer is supported on Solaris and Oracle Enterprise Linux.
Refer to the static code analysis blog entry for a quick summary of steps involved in performing static analysis. The focus of this blog entry is the dynamic portion of the analysis. In this context, dynamic analysis is the evaluation of an application during runtime for memory related errors. Main objective is to find and debug memory management errors -- robustness and security assurance are nice side effects however limited their extent is.
Code Analyzer relies on another primary Solaris Studio tool, discover
, to find runtime errors that are often caused by memory mismanagement. discover
looks for potential errors such as accessing outside the bounds of the stack or an array, unallocated memory reads and writes, NULL pointer deferences, memory leaks and double frees. Full list of memory management issues analyzed by Code Analyzer/discover
is at: Dynamic Memory Access Issues
discover
performs the dynamic analysis by instrumenting the code so that it can keep track of memory operations while the binary is running. During runtime, discover
monitors the application's use of memory by interposing on standard memory allocation calls such as malloc(), calloc(), memalign(), valloc()
and free()
. Fatal memory access errors are detected and reported immediately at the instant the incident occurs, so it is easy to correlate the failure with actual source. This behavior helps in detecting and fixing memory management problems in large applications with ease somewhat. However the effectiveness of this kind of analysis highly depends on the flow of control and data during the execution of target code - hence it is important to test the application with variety of test inputs that may maximize code coverage.
High-level steps in using Code Analyzer for Dynamic Analysis
Given the enhancements and incremental improvements in analytical tools, Solaris Studio 12.4 is recommended for this exercise.
-
Build the application with debug flags
–g
(C) or-g0
(C++) options generate debug information. It enables Code Analyzer to display source code and line number information for errors and warnings.- Linux users: specify
–xannotate
option on compile/link line in addition to-g
and other options
- Linux users: specify
-
Instrument the binary with
discover
% discover -a -H <filename>.%p.html -o <instrumented_binary> <original_binary>
where:
-
-a
: write the error data tobinary-name.analyze/dynamic
directory for use by Code Analyzer -
-H
: write the analysis report to <filename>.<pid>.html when the instrumented binary was executed.%p
expands to the process id of the application. If you prefer the analysis report in a plain text file, use-w <filename>.%p.txt
instead -
-o
: write the instrumented binary to <instrumented_binary>
Check Command-Line Options page for the full list of
discover
supported options. -
-
Run the instrumented binary
.. to collect the dynamic memory access data.
% ./<instrumented_binary> <args>
-
Finally examine the analysis report for errors and warnings
Example
The following example demonstrates the above steps using Solaris Studio 12.4 C compiler and discover
command-line tool. Same code was used to demonstrate static analysis steps as well.
% cat someapp.c #include <stdio.h> #include <stdlib.h> #define SIZE 3 int main() { int *arrX[SIZE]; for (int i = 0; i < SIZE; ++i) { arrX[i] = calloc(1, sizeof(int)); *arrX[i] = (i*5); } for (int i = 1; i <= SIZE; ++i) { printf("\narrX[%d] = %d", i, *arrX[i]); free(arrX); } return 0; } % cc -V cc: Sun C 5.13 SunOS_sparc 2014/10/20 % cc -g -o someapp someapp.c % discover -a -w dynanalysis.%p.txt -o someapp.dyn someapp discover: (warning): /var/tmp/someapp: 94.3% of code instrumented (4 out of 5 functions). % ./someapp.dyn arrX[1] = 5 arrX[2] = 10Segmentation Fault (core dumped) % cat dynanalysis.4492.txt ERROR 1 (BFM): freeing wrong memory block "arrX" at address 0xffbffb00 at: main() + 0x214 <someapp.c:17> 14: 15: for (int i = 1; i <= SIZE; ++i) { 16: printf("\narrX[%d] = %d", i, *arrX[i]); 17:=> free(arrX); 18: } 19: 20: return 0; _start() + 0x108 ERROR 2 (UMR): accessing uninitialized data at address 0xffbffb0c (4 bytes) on the stack at: main() + 0x1c0 <someapp.c:16> 13: } 14: 15: for (int i = 1; i <= SIZE; ++i) { 16:=> printf("\narrX[%d] = %d", i, *arrX[i]); 17: free(arrX); 18: } 19: _start() + 0x108 ERROR 3 (IMR): read from invalid memory at address 0x0 (4 bytes) at: main() + 0x200 <someapp.c:16> 13: } 14: 15: for (int i = 1; i <= SIZE; ++i) { 16:=> printf("\narrX[%d] = %d", i, *arrX[i]); 17: free(arrX); 18: } 19: _start() + 0x108
Few things to be aware of:
- If the target application preloads one or more functions using
LD_PRELOAD
environment variable thatdiscover
tool need to interpose on for dynamic analysis, the resulting analysis may not be accurate. - If the target application uses runtime auditing using
LD_AUDIT
environment variable, this auditing will conflict withdiscover
tool's use of auditing and may result in undefined behavior.
Reference & Recommended Reading:
No comments:
Post a Comment