When PVS-Studio was informed that they finally released a standalone version that does not require Visual Studio for their work, I, of course, could not pass by :) Before that, I was already playing with a trial version on the code of one of the old projects . Now it is possible to look at the code of our last project, which is collected in the AVR Studio development environment (which is eclipse-based).
To work requires files immediately after the preprocessor. AVR Studio is able to do this, with one small exception - after turning on the “Preprocessor only” flag, files after the preprocessor really appear at the output - but still with the extension .o instead of the expected .i. Well, the 5-minute Python script resolves this misunderstanding, and the analyzer runs perfectly!
Surprisingly, there are few messages - about two dozen. Most - insignificant comments or false positives (in embedded writing to the register of the same value twice occurs in a row, the analyzer sees this as a potential problem (and I generally agree with it - it's better to be safe and check these places)).
')
In a couple of places there are real typos and copy-paste errors. For example, a type variable of one enum-a is compared with a value from another enum-a. Or, one variable is assigned two different values ​​in a row (although, as stated above, in most cases this was a false positive for the sequence entries in the register).
But the most interesting, which is why I am writing this post, was one and only line “Possible NULL pointer dereferencing” ...
It so happened that everywhere in the code was used the construction of the form
void fun(error_t * perr) { *perr = SUCCESS; ... if (something) { *perr = SOME_ERROR; } }
And literally in several functions the design was slightly different:
void init(void) { error_t err = SUCCESS; ... fun(&err); }
Until one day after one of the small refactorings, the following appeared in one of the places:
void some_init(void) { error_t *perr = SUCCESS; ... some_fun(perr); }
Actually on this line the analyzer also cursed. SUCCESS, of course, had a value of 0.
We rewind the time a little back, by the time this change hits the repository.
After refactoring, a very large set of automated tests continued to run successfully. The code review left this line unnoticed (too often in the code the lines * perr = SUCCESS flashed).
About 30 days after that commit, the night tests fell for the first time. Play fall failed.
Then the tests fell again. And further. It was experimentally established that a fall occurs on average once per thirty test test runs.
The team spent about 50 hours searching for errors. Unsuccessfully. True, it was possible to localize the commit, after which everything started - but the reason was never found.
The reason, by the way, was two steps lower. The function some_fun (perr) inside itself caused some_other_fun (perr), and that one - some_third_fun (perr). And already in some_third_fun (perr) there was a code that checks for the occurrence of an error:
for(number_of_loops) { some_action(perr); if (*perr != SUCCESS) return; }
Those. despite the fact that in the some_action function (which was very nontrivial, using a bunch of external peripherals - because of which it was not an easy task to localize the problem) no errors occurred, the continuation of the cycle depended on the value written to 0 address (in embedded zero address is quite legal in most cases). In most cases, 0 was recorded at this address.
Summary: the error, the detection of which was unsuccessfully spent about 50 hours, with the help of a single launch of the analyzer was detected and corrected in less than an hour!
Convincing argument to use the analyzer? Alas, not always. In particular, we have the very case: the project with payment according to the time and material scheme. Since the 50 hours spent on the search are paid by the customer, to guide the introduction of the analyzer means direct losses: (((
Also, by the way: the project uses FreeRTOS. So, in her code there was not a single warning!
And yes, this post is exclusively for the love of
art analyzers.