JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Oracle Solaris Studio 12.3 Code Analyzer Tutorial     Oracle Solaris Studio 12.3 Information Library
search filter icon
search icon

Introduction

Getting the Sample Application

Collecting and Displaying Data

Collecting and Displaying Static Error Data

Collecting and Displaying Dynamic Memory Usage Data

Collecting and Displaying Code Coverage Data

Using the Issues Found by the Code Analyzer to Improve Your Code

Potential Errors Found by Code Analyzer Tools

Static Code Issues

Dynamic Memory Access Issues

Code Coverage Issues

Oracle® Solaris Studio 12.3 Code Analyzer Tutorial

December 2011

This tutorial uses a sample program to demonstrate how to use the Oracle Solaris Studio compilers, the Discover memory error discovery tool, the Uncover code coverage tool, and the Code Analyzer GUI to find and correct common programming errors, dynamic memory access errors, and code coverage issues.

Introduction

The Oracle Solaris Studio Code Analyzer is an integrated set of tools designed to help developers of C and C++ applications for Oracle Solaris produce secure, robust, and quality software.

The Code Analyzer includes three types of analysis:

Static code checking detects common programming errors in your code during compilation. A new compiler option leverages the Oracle Solaris Studio compilers' extensive and well proven control and data flow analysis frameworks to analyze an application for potential programming and security flaws.

The Code Analyzer uses dynamic memory data collected by Discover, the memory error discovery tool in Oracle Solaris Studio, to find memory-related errors when you run your application. It uses data collected by Uncover, the code coverage tool in Studio, to measure code coverage.

In addition to giving you access to each individual type of analysis, the Code Analyzer integrates static code checking and dynamic memory access checking to add confidence levels to errors found in code. By using static code checking together with dynamic memory access analysis and code coverage analysis, you will be able to find many important errors in your applications that cannot be found by other error detection tools working by themselves.

Getting the Sample Application

This tutorial uses a sample program to demonstrate how to use the Oracle Solaris Studio compilers, the Discover memory error discovery tool, the Uncover code coverage tool, and the Code Analyzer GUI to find and correct common programming errors, dynamic memory access errors, and code coverage issues.

The source code for the sample program is available in the sample applications zip file on the Oracle Solaris Studio 12.3 Sample Applications web page at http://www.oracle.com/technetwork/server-storage/solarisstudio/downloads/solaris-studio-samples-1408618.html. If you have not already done so, download the sample applications zip file and unpack it in a directory of your choice.

The sample application is located in the CodeAnalyzer subdirectory of the SolarisStudioSampleApplications directory.

The sample directory contains the following source code files:

main.c
previse_1.c
previse_all.c
sample_1.c
sample_2.c
sample_3.c

Collecting and Displaying Data

You can use the Code Analyzer tools to collect one, two, or all three types of data.

Collecting and Displaying Static Error Data

When you build a binary using the -xanalyze=code compiler option, the compiler automatically extracts static errors and puts the data in a static subdirectory in a binary_name.analyze directory in the same directory as the source code. For a list of the types of static errors found by the compiler, see Static Code Issues.

  1. In your sample directory, build the application by typing:

    cc -xanalyze=code *.c

    The static error data is written to the static subdirectory in an a.out.analyze directory in your sample directory.

  2. Open the Code Analyzer GUI to view the results:

    code-analyzer a.out &
  3. The Code Analyzer GUI opens and the Results tab displays the static code issues found during compilation. The text at the top of the Results tab tells you that twelve static code issues were found.

    image:Code Analyzer Results tab displaying static issues
  4. For each issue, the tab displays the issue type, the path name of the source file in which the issue was found, and a code snippet from that file with the relevant source line highlighted.

  5. To see more information about the first issue, a Double Freeing Memory error, click the error icon image:error icon. The stack trace for the issue opens displaying the error path.

    image:Double Freeing Memory error showing error path
  6. Notice that when you opened the stack trace, the icon in the upper right corner of the issue changed from image:unvisited icon to image:visited icon to indicate that you have reviewed the issue.


    Note - You can hide the issues you have reviewed by clicking the Hide Reviewed Issues button image:hide reviewed issues buttonat the top of the Results tab. Clicking the button again unhides the issues.


  7. Click the error icon to close the stack trace.

  8. Now look at one of the Unitialized Memory Read warnings. Click the warning icon image:warning icon to open the stack trace. Notice that the error path for this issue contains many more function calls than the one for the Double Freeing Memory issue. Double click on the first function call. The source file opens with that call highlighted. The error path is displayed in a Details Window below the source code.

    image:Source code window with function call highlighted and error path displayed below

    Double click the rest of the function calls in the error path to follow the path through the code that leads to the error.

  9. To see more information about the UMR error type, click the Info button image:info button to the left of the issue description. A description of the error type, including a code example and possible causes, is displayed in the online help browser.

  10. Close the Code Analyzer GUI.

Collecting and Displaying Dynamic Memory Usage Data

Whether or not you have collected static data, you can compile, instrument, and run your application to collect dynamic memory access data. For a list of the dynamic memory access errors found by instrumenting your application with Discover and then running it, see Dynamic Memory Access Issues.

  1. In your sample directory, build the sample application with the -g option. This option generates debug information that allows the Code Analyzer to display source code and line number information for errors and warnings.

    cc -g *.c
  2. You cannot instrument a binary that is already instrumented, so save a copy of the binary to use when you collect coverage data.

    cp a.out a.out.save
  3. Instrument the binary with Discover:

    discover -a a.out
  4. Run the instrumented binary to collect the dynamic memory access data.

    ./a.out

    The dynamic memory access error data is written to the dynamic subdirectory in the a.out.analyze directory in your sample directory.

  5. Open the Code Analyzer GUI to view the results:

    code-analyzer a.out &
    image:Code Analyzer Results tab showing static and dynamic errors
  6. The Results tab now shows both static issues and dynamic memory issues. The background color behind an issue description indicates a static code issue (tan) or a dynamic memory access issue (pale green).

    To filter the results and show just the dynamic memory issues, select the Dynamic checkbox on the Issues tab.

    image:Issues tab showing check in checkbox for dynamic issues

    Now the Results tab shows just the three core dynamic memory issues.


    Note - Core issues are the issues that, when fixed, are likely to eliminate the other issues. A core issue usually combines several of the issues listed on the All view because, for example, those issues have a common allocation point, or they occur at the same data address in the same function.


  7. To see all of the dynamic memory issues, select the All radio button at the top of the Issues tab. Now the Results tab displays six dynamic memory issues.

    image:Code Analyzer Results tab showing six dynamic memory issues

    Look at the three issues that were added to the display and see how they are related to the core issues. It looks as though fixing the cause of the first issue in the display is likely to also eliminate the second and third issues.

    To hide the other three dynamic memory access issues while you investigate these first one, click the Ignore button image:ignore buttonfor each of the issues.


    Note - You can later redisplay the closed issues by clicking the Show Ignored Issues button image:show ignored issues button at the top of the Results tab.


  8. Investigate the first issue by clicking the error icon image:error icon to display the stack trace. For this issue, the stack trace includes the Call Stack and the Allocated At Stack.

    image:Stack trace for Uninitialized Memory Read error

    Double-click function calls in the stacks to see the associated lines in the source file. When the source file opens, the stack trace is displayed in a Details window below the file.

    image:Source file for Uninitialized Memory Read error with Details window
  9. Close the Code Analyzer GUI.

Collecting and Displaying Code Coverage Data

Whether or not you have collected static data or dynamic memory access data, you can compile, instrument, and run your application to collect code coverage data.

  1. Since you built the application with the -g option before you collected dynamic memory error data and saved a copy of the binary before instrumenting it, you can copy the saved binary to instrument for coverage data collection.

    cp a.out.save a.out
  2. Instrument the binary with Uncover:

    uncover a.out
  3. Run the instrumented binary to collect the code coverage data.

    ./a.out

    The code coverage data is written to an a.out.uc directory in your sample directory.

  4. Run Uncover on the a.out.uc directory.

    uncover -a a.out.uc

    The code coverage data is written to an uncover subdirectory in the a.out.analyze directory in your sample directory.

  5. Open the Code Analyzer GUI to view the results:

    code-analyzer a.out &
  6. The Results tab now shows static issues, dynamic memory issues, and code coverage issues. To filter the results and show just the code coverage issues, select the Coverage checkbox on the Issues tab.

    Now the Results tab shows just the twelve code coverage issues. The description of each issue includes a potential coverage percentage, which indicates the percentage of coverage that will be added to the total coverage for the application if a test covering the relevant function is added.

    image:Code Analyzer Results tab showing some of the code coverage issues

    Note - To see all of the issues without scrolling up and down, click the Hide Snippets button image:hide snippets button at the top of the Results tab to hide the code snippets.


  7. In the Issues tab, notice that nine of the coverage issues are in the previse_all.c source file, three of them are in sample2.c, and one is in previse_1.c. To further filter the results and show just the issues for the sample2.c file, select the checkbox for that file on the Issues tab.

    The Results tab now shows just the three code coverage issues found in sample2.c.

    image:Code Analyzer Results tab showing code coverage errors for sample2.c
  8. Open the source file by clicking on the source file path link in one of issues. Scroll down in the source file until you see the warning icons in the left margin.

    image:Portion of source file with uncovered code and warning icons for coverage issues

    Code that is not covered is marked with a yellow bracket, for example image:Left square bracket filled with yellow marking two lines of code. The coverage issues found in the file are marked with warning icons image:Warning issue icon

Using the Issues Found by the Code Analyzer to Improve Your Code

By fixing the core issues found by the Code Analyzer, you should be able to eliminate the other issues found in your code, and make major improvements in its quality and stability.

By doing static error checking, you can find the risky code in your application. But static error checking can generate false positives. Dynamic checking can help verify and eliminate these errors, giving a more accurate picture of the issues in your code. And code coverage checking can help you improve your dynamic test suites.

The Code Analyzer integrates the results these three types of checking to give you the most accurate analysis of your code all in one tool.

Potential Errors Found by Code Analyzer Tools

The compilers, Discover, and Uncover find static code issues, dynamic memory access issues, and coverage issues in your code. The specific error types that are found by these tools and analyzed by the Code Analyzer are listed in the following sections.

Static Code Issues

Static code checking finds the following types of errors:

Dynamic Memory Access Issues

Dynamic memory access checking finds the following types of errors:

Dynamic memory access checking finds the following types of warnings:

Code Coverage Issues

Code coverage checking determines which functions are uncovered. In the results, code coverage issues found are labeled as Uncovered Function, with a potential coverage percentage, which indicates the percentage of coverage that will be added to the total coverage for the application if a test covering the relevant function is added.