This blog post goes over how a student can statically analyze their C/C++ code with PVS-Studio for free on Ubuntu.

The PVS-Studio team wrote a fascinating post called 100 bugs in Open Source C/C++ projects, which I highly recommend checking out.

Setup

  1. Install pvs-studio on Ubuntu from the App Center (or using the PVS-Studio installation page for students)
  2. Run pvs-studio-analyzer credentials PVS-Studio Free FREE-FREE-FREE-FREE to activate a free student license
  3. Add this comment to the top of your C file:
// This is a personal academic project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: https://pvs-studio.com

Usage

// This is a personal academic project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: https://pvs-studio.com

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *foo = malloc(sizeof(int));

    *foo = 42;

    printf("%d\n", *foo);

    free(foo);
}

Compiling this program with lots of warnings turned on and fsanitize makes it seem like the program works fine, since it prints 42 successfully:

clang foo.c -Wall -Wextra -Werror -Wpedantic -fsanitize=address,undefined && ./a.out

But there’s actually a bug in this function. Let’s use PVS-Studio to find it for us!

  1. Generate strace_out with pvs-studio-analyzer trace -- gcc foo.c
  2. Generate pvs.log with pvs-studio-analyzer analyze -o pvs.log
  3. Generate pvs.json with plog-converter -a GA:1,2 -t json -o pvs.json pvs.log (run plog-converter --help to get descriptions of these flags)

If you install the PVS-Studio extension for VS Code, you should see this PVS-STUDIO tab appear in the bottom panel (if you don’t see it, refer to the extension’s official PVS-Studio guide):

PVS-STUDIO tab

Inside of the PVS-STUDIO tab, click the Open report button, and select the pvs.json file we generated. You should now see this:

PVS-Studio report

It warns about lines 8 and 10, which correspond to the malloc() and *foo = 42; lines.

The message There might be dereferencing of a potential null pointer 'foo' is completely correct, and we can resolve it by adding this right after the malloc() call:

if (!foo) {
    return EXIT_FAILURE;
}

PVS-Studio report with 0 warnings