Coverity static analysis

This page demonstrates the use of the Coverity static analysis tool for bug detection.

Prerequisite: Coverity should be configured for the language/compiler that you are using. For example, if using java, Coverity should be configured to use the javac compiler.

Table of Contents

  1. Inspecting Defects Using Coverity Platform
    1. Log In to Platform
    2. Inspect Coverity and FindBugs Warnings
  2. How to Compile and Analyze Java and C/C++ Programs using the command line?
    1. Create a project and a stream
    2. Log In to Coverity Linux Servers
    3. Create an Intermediate Directory
    4. Configure the Build Script
    5. Run Coverity's Build Command
    6. Analyze the Output
    7. Commit the Defects
    8. Find and Fix Bugs
  3. Reference Material (Further Reading).

Inspecting Defects Using Coverity Platform

1) Log in to Platform

coverity.cs.purdue.edu can only be accessed on campus. If you want to connect it off-campus, please connect to Purdue VPN first

Platform is installed as a web application. Navigate to https://coverity.cs.purdue.edu:8443. An email should have been sent to you to guide you to setup an account.

2) Inspect Coverity and Findbugs Warnings

In the navigation tree on the left-hand side of the page, select "Outstanding Issues". This provides a summary of the warnings found in the analysis of the Apache Commons library. Click on one of the warnings. The source code associated with the warning will appear in the pane below the warning list. On the right-hand side of the screen is more information about the warning.

To assist in triaging the warnings, you may want to look at the events in the source code that led the checker to produce a warning. The events are shown under the "Occurrences" menu in the panel on the right.

How to Compile and Analyze Java and C/C++ Programs Using Coverity using command line

Coverity is installed on the Coverity Linux servers at path /opt/coverity/cov-analysis-linux64-2021.12.1/.

1) Create a project and a stream

Connect to https://coverity.cs.purdue.edu:8443 with the credentials you received by email. Click on "Configuration", "Projects & Streams" and click on "+Project" to create your project. Name it gXX_project. Then select your project and click on "+Stream" to create a stream in your project. Call it also "gXX_project". Then, in the "Roles" tab, click on "add" and check the box "No Access" for the group "Students".

2) Log In to Coverity Linux Servers

You can access the server by logging in to coverity.cs.purdue.edu through ssh. All of the following steps in this tutorial should be performed from the home directory of your CS Linux account.

Coverity is only installed on coverity.cs.purdue.edu. Make sure you are connecting to it to use Coverity, otherwise, it won't work!

3) Create an Intermediate Directory.

The intermediate directory is where Coverity stores all the files associated with the analysis. Both the compiled code as well as the results are stored in this directory. Create an output directory in your home directory on CS Linux for your static analysis:

mkdir ~/sa_output

Next, create the directory for the intermediary files. Hint: append the revision number to this directory to avoid overwriting this directory in the future.

mkdir ~/sa_output/intermediate_r[revision]

Copy your project files to the intermediate directory.

4) Configure the Build Script

Coverity will use the build script that you pass to it and intercept any calls to your compiler. For Java this is javac while for C/C++ Coverity is configured for g++ or gcc This means that you can pass Coverity pretty much any build script, including shell scripts, Apache Ant, make, cmake etc. Ensure your build script is functioning properly by first building the program without Coverity.

5) Run Coverity's Build Command

This will compile your program. The build will be intercepted by Coverity and the intermediary files needed for analysis will be created here. Depending on the size of the program, this step could take some time (~1 hour for 1MLOC). The format for this command is cov-build --dir [intermediate_directory] [build_command]

/opt/coverity/cov-analysis-linux64-2021.12.1/bin/cov-build --dir ~/sa_output/intermediate_r[revision]/ [build_command]

Examples of [build_command]:

6) Analyze the Output.

Now we can analyze the output of the build and find potential bugs.

/opt/coverity/cov-analysis-linux64-2021.12.1/bin/cov-analyze --dir ~/sa_output/intermediate_r[revision]

7) Commit your defects

/opt/coverity/cov-analysis-linux64-2021.12.1/bin/cov-commit-defects --dir ~/sa_output/intermediate_r[revision] --host coverity.cs.purdue.edu --user gXXX --https-port 8443 --stream gXXX_project

The only things you should change is the user (gXXX) and the stream name (gXXX_project). The stream name should match the stream you created in step 1. Then you will be asked to enter the password for your group

8) Find and Fix Bugs

If the commit is successfull, you should be able to see your project on https://coverity.cs.purdue.edu:8443 with your credentials and navigate to your project to see the list of errors.

If the commit fail, you can still see the output from the analysis is located in ~/sa_output/intermediate_r[revision]/output/[CHECKER].errors.xml. Each checker looks for different bug types. Read checker_ref.pdf (see Reference Material section) for details on what each checker looks for. Note that C/C++ has different checkers than Java.

The following snippet is taken from FORWARD_NULL.errors.xml during an analysis of Tomcat6:

<error>
  <checker>FORWARD_NULL</checker>
  <file>/home/user/tomcat6/java/org/apache/tomcat/util/buf/MessageBytes.java</file>
  <function>org.apache.tomcat.util.buf.MessageBytes.equalsIgnoreCase(java.lang.String)</function>
  <score>100</score>
  <ordered>true</ordered>
  <event>
   <tag>switch</tag>
   <description>{CovLStr{v1}{Switch case value {0}}{"1"}}</description>
   <line>328</line>
   <path_event>
   <jump>true</jump>
   </path_event>
  </event>
  ...
  <event>
   <main>true</main>
   <tag>null_method_call</tag>
   <description>{CovLStr{v1}{Calling a method on null object {0}.}{"strValue"}}</description>
   <line>331</line>
  </event>
  <extra>strValue</extra>
  <subcategory>none</subcategory>
</error>

Each error is represented by an error element (<error></error>). Within the error element, you can view the potential bug as well as the reasoning behind why Coverity believes it is a bug. In this example, Coverity deduces that a method is called on a null object at line 331. Each step leading up to this conclusion, as well as the conclusion itself, can be viewed in <event> elements. To resolve this particular warning, the developer might remove the method call, initialize the object before the method call or change the conditional statements leading up to the method call.

Reference Material

Reference material can be found in the documentation directory of the Coverity installation, which is at /opt/coverity/cov-analysis-linux64-2021.12.1/doc/en. The following manuals are useful for learning how to run Coverity static analysis:

1) cov_command_ref.pdf

Demonstrates the command line operations needed to compile and analyze your program using Coverity.

2) cov_checker_ref.pdf

Describes the static checkers (or rules) that Coverity uses to detect defects. Each checker detects a certain type of defect. Use this guide to learn what problems Coverity found with your program and how to fix them.

3) cov_analysis_administration_guide.pdf

Provides getting started guides for c and java.

5) https://coverity.cs.purdue.edu:8443/doc/en/index.html

General documentation of Coverity.