具有SAL批注的Visual Studio社区代码分析的质量

时间:2018-08-20 14:53:10

标签: c++ visual-studio-2017 static-analysis sal

我希望这个问题不会超出SO的范围;如果是(在这种情况下很抱歉),请告诉我它的位置,我将尝试将其移到那里。

在C / C ++中用于静态代码分析的SAL annotations的概念对我来说真的很有用。以MSDN: Understanding SAL上错误实现的wmemcpy示例为例:

wchar_t * wmemcpy(
   _Out_writes_all_(count) wchar_t *dest,
   _In_reads_(count) const wchar_t *src,
   size_t count)
{
   size_t i;
   for (i = 0; i <= count; i++) { // BUG: off-by-one error
      dest[i] = src[i];
   }
   return dest;
}

MSDN说,“一个代码分析工具可以通过单独分析此函数来捕获错误” ,这似乎很棒,但是问题是,当我将此代码粘贴到VS 2017 Community中时,没有关于这会在代码分析时弹出,甚至没有启用所有分析警告。 (其他警告,例如C26481 Don't use pointer arithmetic. Use span instead (bounds.1).也会这样做。)

另一个示例,该示例应产生警告(至少根据an answer to What is the purpose of SAL (Source Annotation Language) and what is the difference between SAL 1 and 2?),但不会:

_Success_(return) bool GetASmallInt(_Out_range_(0, 10) int& an_int);

//main:
int result;
const auto ret = GetASmallInt(result);
std::cout << result;

还有一个错误警告的情况:

struct MyStruct { int *a; };

void RetrieveMyStruct(_Out_ MyStruct *result) {
    result->a = new int(42);
}

//main:
MyStruct s;
RetrieveMyStruct(&s);
 // C26486 Don't pass a pointer that may be invalid to a function. Parameter 1 's.a' in call to 'RetrieveMyStruct' may be invalid (lifetime.1).
 //  Don't pass a pointer that may be invalid to a function. The parameter in a call may be invalid (lifetime.1).

result明显标有_Out_而不是_In__Inout_,因此在这种情况下此警告没有意义。

我的问题是:为什么Visual Studio基于SAL的代码分析似乎很糟糕;为什么?我是否缺少某些东西?在这方面,Visual Studio Professional或Enterprise可能更好吗?还是有一个工具可以更好地做到这一点?

如果真的很糟糕:这是一个已知问题吗,也许有计划改进这种类型的分析吗?

相关:visual studio 2013 static code analysis - how reliable is it?

1 个答案:

答案 0 :(得分:0)

Functions contracts(其中的SAL注释是一种轻量级的实现),使可以本地推理某个函数是在做正确的事情还是被错误使用或相反。没有它们,您只能在整个程序的上下文中讨论错误的概念。正如文档所述,有了它们,就可以在本地说出函数的行为是一个错误,并且您可以希望静态分析工具能够找到它。

即使有此帮助,也要机械地验证一段代码没有错误,这仍然是一个难题。由于存在多种解决问题的方法,因此存在不同的技术。它们都有优点和缺点,并且都包含许多启发式方法。循环是导致难以预测程序所有行为的部分原因,这些工具的实现者可能会选择不对极端简单的循环进行硬编码,因为这些模式在实践中很少使用。

  

如果真的很糟糕:这是一个已知问题吗,也许有计划改进这种类型的分析吗?

是的,研究人员已经在这个主题上研究了数十年,并继续改进理论和将理论思想转化为实用工具。作为用户,您可以选择:

  • 如果您需要没有代码的错误,例如因为它是针对安全性高的上下文而设计的,那么您已经基于每个级别的密集测试采用了非常繁琐的方法V周期,这种静态分析已经可以帮助您以更少(但有些)的努力达到相同的置信度。为此,您将需要比SAL注释更具表现力的合同规范。例如C的ACSL
  • 如果您不愿意付出必要的努力来确保代码高度自信地消除错误,则仍然可以利用这种静态分析,但是在这种情况下,可以将发现的任何错误视为奖励。 。由于注释具有正式定义的含义,因此即使在不涉及静态分析器的手动代码审查的情况下,注释也可以用于分配责任。 SAL注释是为此用例明确设计的。