PVS Studio.VS。GCC 10的统计分析

在出现有关GCC 10中静态分析的翻译文章,以及在这里的商用静态分析仪PVS-Studio的开发人员的代表的预期反应之后,我问:“为什么代表们拒绝使用如此简单的静态分析示例来测试其产品,他们是否隐藏了?这些是什么? ”
安德烈2008是的,这对我来说并不有趣。捕获/未捕获到综合错误,这并未说明分析仪的功能
他们应该以某种方式对产品进行单元测试吗?如果不使用这样简单的综合示例,该如何进行?

实际上,我必须自己做。

测试编号1。双精度错误的最简单示例


诊断与:
V586为释放相同的内存空间,两次调用了“ free”功能。检查第一个参数。检查行:5、6。1_dbl_free.c 6

通过

测试编号2。longjmp()由免费()


malloc中的常量发誓难以理解,但检测到错误-无法访问的代码和未使用的内存:
V118 malloc()函数以参数的形式接受危险的表达式。2_longjump.c 13
V779检测到无法访问的代码。可能存在错误。2_longjump.c 15
V799在为其分配了内存之后,不再使用'ptr'变量。考虑检查此变量的使用。2_longjump.c 13

通过

测试编号3。Malloc()泄漏和fopen()未关闭文件


发现:
V118 malloc()函数以参数的形式接受危险的表达式。3_fopen.c 7
V773退出了“ f”文件句柄的可见性范围,而没有关闭文件。资源泄漏是可能的。3_fopen.c 9
V773退出了“ p”指针的可见性范围,而没有释放内存。可能发生内存泄漏。3_fopen.c 9
V799在为其分配了内存之后,不再使用'p'变量。考虑检查此变量的使用。3_fopen.c 7

通过

测试编号4。释放后监视内存使用情况


检测到错误:
V774释放内存后使用了'n'指针。4_use_after_free.c 9
V591非void函数应返回一个值。4_use_after_free.c 11

通过

测试编号5。非堆指针释放控制(堆)


发出了非错误警告:
V104在算术表达式中将'n'隐式转换为memsize类型:sizeof(int)* n 5_free_nonheap.c 11
V799在为其分配了内存之后,不再使用'ptr'变量。考虑检查此变量的使用。5_free_nonheap.c 11

失败

测试编号6。无效的signal()处理程序内部调用


失败,

尽管这是一种非常具体的诊断,所以我不会对此进行指责。

接下来,我浏览了GCC 10中的诊断程序列表并添加了示例,以便使用源代码进行进一步测试。

测试编号7。双重关闭文件并释放关闭的文件*


PVS未检测到这些错误,
GCC 10检测到两次闭合,但对于闭合手柄未检测到自由。

#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。污染数组索引和未初始化值的使用诊断


看来他们还没有在GCC10- fanalyzer中工作

正如许多次证明的那样,PVS抓住了这一点。

已通过

结论


PVS-Studio中肯定有静态分析。

尽管并非没有缺点,但值得使用它,特别是因为不仅可以从静态分析领域中检测到许多人为错误,还可以检测到它。

All Articles