После появления переводной статьи про Статический анализ в GCC 10, и ожидаемой реакции присутствующих здесь представителей разработчика коммерческого статического анализатора PVS-Studio, у меня возник вопрос: «Почему же представители отказываются проверить свой продукт на таких простых примерах для статического анализа, и не скрывают ли они чего?»
Andrey2008 Ды, неинтересно мне это. Поймал/не поймал синтетическую ошибку, это ничего не говорит о возможностях анализатора
Должны же они как то прогонять юнит-тесты своего продукта и как, если не на таких синтетических простых примерах?!
Собственно, пришлось сделать это самому.
Тест №1. Самый простой пример ошибки double-free
Обнаружена с диагностикой:
V586 The 'free' function is called twice for deallocation of the same memory space. Inspect the first argument. Check lines: 5, 6. 1_dbl_free.c 6
Пройден
Тест №2. longjmp() мимо free()
Непонятная ругань на константу в malloc, но ошибка обнаружена — недоступный код и неиспользованная память:
V118 malloc() function accepts a dangerous expression in the capacity of an argument. 2_longjump.c 13
V779 Unreachable code detected. It is possible that an error is present. 2_longjump.c 15
V799 The 'ptr' variable is not used after memory has been allocated for it. Consider checking the use of this variable. 2_longjump.c 13
Пройден
Тест №3. Утечки malloc() и незакрытые файлы fopen()
Обнаружены:
V118 malloc() function accepts a dangerous expression in the capacity of an argument. 3_fopen.c 7
V773 Visibility scope of the 'f' file handle was exited without closing the file. A resource leak is possible. 3_fopen.c 9
V773 Visibility scope of the 'p' pointer was exited without releasing the memory. A memory leak is possible. 3_fopen.c 9
V799 The 'p' variable is not used after memory has been allocated for it. Consider checking the use of this variable. 3_fopen.c 7
Пройден
Тест №4. Контроль использования памяти после ее освобождения
Баг обнаружен:
V774 The 'n' pointer was used after the memory was released. 4_use_after_free.c 9
V591 Non-void function should return a value. 4_use_after_free.c 11
Пройден
Тест №5. Контроль освобождения указателя не на кучу (heap)
Выданы предупреждения, не относящиеся к ошибке:
V104 Implicit conversion of 'n' to memsize type in an arithmetic expression: sizeof (int) * n 5_free_nonheap.c 11
V799 The 'ptr' variable is not used after memory has been allocated for it. Consider checking the use of this variable. 5_free_nonheap.c 11
Провален
Тест №6. Недопустимый вызов внутри обработчика signal()
Провален
Хотя это настолько специфическая диагностика, что я бы не ставил ее в укор.
Далее я прошелся по перечню диагностик в GCC 10 и дописал примеры, потому дальнейшие тесты с исходниками.
Тест №7. Двойное закрытие файла и освобождение закрытого FILE*
PVS не обнаружил этих ошибок
GCC 10 обнаружил double-fclose но не обнаружил free для закрытого хендла.
#include <stdlib.h>
void closefile(FILE* f) {
fclose(f);
}
void test(const char *filename) {
FILE *f = fopen(filename, "r");
void *p = malloc(1024);
/* do stuff */
closefile(f);
fclose(f);
free (p);
free(f); // <- UB
}
Провален
Тест №8. longjmp() на устаревший стек
PVS не заметил ничего, GCC10 отработал верно
#include <setjmp.h>
#include <stdlib.h>
static jmp_buf env;
static int i;
static void inner(void) {
longjmp(env, 1);
}
static void middle(void) {
inner();
}
void outer(void) {
i = setjmp(env);
}
void outer_x2(void) {
outer();
if (i == 0)
middle();
}
Провален
Тест №9. Возврат указателя на стековую переменную
Провален обоими участниками, хотя в простых случаях GCC обнаруживает такое, но это еще не функция -fanalyzer (а может еще не реализована).
#include<stdlib.h>
struct str1 {
char buf[10];
};
struct str1 * ret(int sel)
{
struct str1 var1, *pval;
if(sel == 1)
pval = &var1;
else if(sel != 1)
pval = (struct str1 *)malloc(1000);
return pval;
}
Провален
Тест №10. Диагностики tainted-array-index и use-of-uninitialized-value
Похоже, еще не работают в GCC10 -fanalyzer.
PVS такое отлавливает, как много раз уже демонстрировалось.
Пройден
Вывод
Статический анализ в PVS-Studio определенно есть.
Хотя и не без некоторых недостатков, но и им стоит пользоваться, тем более, что будут обнаружены и многие человеческие ошибки, не только из области статического анализа.
Автор: Siemargl