GTK: What the first run of the analyzer looks like in numbers

For some people, introducing a static analyzer into a project looks like an insurmountable obstacle. For some reason, the opinion is very widespread that the volume of the analysis results issued at the first launch is so large that only two options are considered: do not mess with it or switch all people to fix warnings. In this article, we will try to dispel this myth by implementing and configuring the analyzer on a GTK project.

Introduction

GTK – cross-platform library of interface elements. Recently, GTK 4 was released, which became a good informational reason to study the quality of the project code using a static code analyzer PVS-Studio… Such activity for us is regularand we often have to set up the analyzer from scratch on many projects before examining the quality of the code. In this post I will share my experience of quickly setting up PVS-Studio on a C ++ project.

GTK Analysis

First results

We receive our first analyzer report and see the following results for general diagnostics:

4 (Fails) + 1102 (High) + 1159 (Medium) + 3093 (Low) = 5358 warnings.

Then we quickly scroll through the report, detect bursts of uninteresting warnings and make a decision for further configuring the analyzer.

Excluding directories

Consider a warning like this:

V530 [CWE-252] The return value of function ‘g_strrstr_len’ is required to be utilized. strfuncs.c 1803

/* Testing functions bounds */
static void
test_bounds (void)
{
  ....
  g_strrstr_len (string, 10000, "BUGS");
  g_strrstr_len (string, 10000, "B");
  g_strrstr_len (string, 10000, ".");
  g_strrstr_len (string, 10000, "");
  ....
}

This is the code of tests that are not directly related to GTK, so we make a list of directories to exclude from analysis and restart PVS-Studio.

At the next launch, the following directories will be excluded from the analysis:

gtk/_build/
gtk/subprojects/
gtk/tests/
gtk/testsuite/

We open the report and get the following result:

2 (Fails) + 819 (High) + 461 (Medium) + 1725 (Low) = 3007 warnings.

Another positive effect that we got after this setup is the acceleration of the analysis.

Excluding macros

Macros are perhaps one of the main reasons for the abnormal number of alerts in some diagnostics. We look at our report superficially and notice many similar warnings:

V501 There are identical sub-expressions ‘* (& pipe-> ref_count)’ to the left and to the right of the ‘^’ operator. gdkpipeiostream.c 65

static GdkIOPipe *
gdk_io_pipe_ref (GdkIOPipe *pipe)
{
  g_atomic_int_inc (&pipe->ref_count);

  return pipe;
}

Making changes to macros is usually the most difficult thing – it is unlikely that someone in the company will undertake this. At first, definitely not. Therefore, we will use the mechanism for disabling diagnostics on them. Having quickly reviewed the report, we compose the following settings file:

#V501
//-V:g_atomic_int_:501
#V547
//-V:GTK_IS_:547
//-V:GDK_IS_:547
//-V:G_IS_:547
//-V:G_VALUE_HOLDS:547
#V568
//-V:g_set_object:568

Just a few lines that cover most of the problematic macros for V501, V547 and V568

Let’s see the result:

2 (Fails) + 773 (High) + 417 (Medium) + 1725 (Low) = 2917 warnings.

Disable diagnostics

Some diagnostics will initially issue inappropriate project-specific warnings. Consider the warning V1042:

V1042 [CWE-1177] This file is marked with copyleft license, which requires you to open the derived source code. main.c 12

This is a very useful diagnostic for closed source projects so that you do not accidentally include code with an invalid license. But for GTK this is not an interesting diagnostic, so disable it and get the corrected result:

2 (Fails) + 164 (High) + 417 (Medium) + 1725 (Low) = 2308 warnings.

Examining Fails

There are 2 Fails warnings in the project:

  • V002 Some diagnostic messages may contain incorrect line number in this file. gdkrectangle.c 1

  • V002 Some diagnostic messages may contain incorrect line number in this file. gdktoplevelsize.c 1

This diagnostic warns that detections on these files may point to the wrong lines of code. Usually the difference is 1-2 lines, and this happens due to incorrect expansion of macros by the compiler. In our experience, most often this was spotted compiler MSVC.

You can simply ignore these warnings.

conclusions

The final result is as follows:

164 (High) + 417 (Medium) + 1725 (Low) = 2306 warnings.

Surely, there is still something to configure, but I have already solved the task that I set myself: to quickly get an analyzer report, in which it is easy to find errors. For example, a warning with the number V501 now there is only one in the whole report, and it is good:

V501 There are identical sub-expressions ‘G_PARAM_EXPLICIT_NOTIFY’ to the left and to the right of the ‘|’ operator. gtklistbase.c 1151

static void
gtk_list_base_class_init (GtkListBaseClass *klass)
{
  ....
  properties[PROP_ORIENTATION] =
    g_param_spec_enum ("orientation",
                       P_("Orientation"),
                       P_("The orientation of the orientable"),
                       GTK_TYPE_ORIENTATION,
                       GTK_ORIENTATION_VERTICAL,
                       G_PARAM_READWRITE |
                       G_PARAM_EXPLICIT_NOTIFY |  // <=
                       G_PARAM_EXPLICIT_NOTIFY);  // <=
  ....
}

This is a great result! And the indicators of other diagnostics also increased significantly. With scanty settings, we managed to reduce the analyzer report by 57%… Accordingly, the rate of true warnings to false ones also increased significantly.

By the way, this is one of the reasons why there are no comparisons of the results of different code analyzers on the Internet. Because there is no consensus on whether it is worth showing the analyzer’s operation as it is, or whether it is still necessary to carry out the initial setup. And all analyzers have their own mechanisms for this, which greatly complicates the complexity of the comparison task.

Now is the time to pass the baton to my colleague Andrey Karpov.

Note by Andrey Karpov

Even such a simple and quick filtering of results, described in this article, greatly simplifies the work with the report. For example, taking this report, during one evening I was able to skim through it and write out code fragments with errors, enough to write an article. Actually, I will write it on the New Year holidays.

Of course, my task is simpler and very different from the process of setting up and implementing the analyzer into a real project. It is enough for me to skim through the list of warnings and write out obvious errors, ignoring false positives or incomprehensible warnings in complex sections of code. In real use, it will take more time to tune the analyzer, suppress false positives, improve macros, and so on. But in fact, it’s not scary. For example, in the article about checking the EFL Core Libraries project I have shown that it is easy enough to configure the analyzer so that it outputs everything 10-15% false warnings. Agree, it’s not bad when for every 1-2 false positives you fix 8-9 errors.

Well, do not forget that you are always available mechanism mass suppression of analyzer responses. This allows you to quickly start using the analyzer, even in a large project. All warnings are announced as technical debt and are not shown yet. And the team starts working only with warnings related to new or changed code. I suggest reading more about this in the article “How to implement a static code analyzer in a legacy project and not demotivate the team“.

Thank you for your attention and come back to read an article about the errors found in a couple of weeks.

If you want to share this article with an English-speaking audience, please use the translation link: Svyatoslav Razmyslov. GTK: The First Analyzer Run in Figures.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *