【问题标题】:Why does Cppcheck not find this obvious array out-of-bounds error?为什么 Cppcheck 没有发现这个明显的数组越界错误?
【发布时间】:2012-08-11 14:08:54
【问题描述】:

我安装了Cppcheck 工具对我的C++ 项目进行静态代码分析,感觉它的性能很差。例如,谁能告诉我为什么 Cppcheck 在以下代码中无法找到数组越界错误?

void f(int c) { 
    char *p = new char[10]; 
    p[c] = 42; 
} 

void g() { 
    f(100); 
} 

有一个online demo 可以使用 Cppcheck 方便地检查此代码。它只是在第 4 行出现内存泄漏,没有潜在缓冲区溢出的迹象。

【问题讨论】:

  • 我注意到您的问题已在 cppcheck 论坛上发布和评论。那里的评论似乎暗示这种类型的边界检查尚不支持。在那个论坛上进一步质疑这个问题可能会更好。
  • 因为任何工具都无法找到所有错误,尤其是 cppcheck 不能完全解析和评估 c++,但包含许多只允许检测大多数本地错误的快捷方式。
  • 描述工具检测错误所需的步骤。然后列举会出现误报的情况。然后试一试,想象开发人员坐下来权衡这些事情。
  • 是的,当我尝试使用 cppcheck 时,我也不太满意。不过,当我有更多代码要检查时,可能会再试一次 :-) 无论哪种方式,您期望得到什么样的答案? cppcheck 不会简单地找到您的错误“因为它不检查特定的事物组合”。 cppcheck 开发人员可能能够解释他们是否只是忘记了那个案例,或者是否需要对 cppcheck 进行不止一行的更改,甚至对模块进行根本性更改,但事实仍然是它还没有完成。 “显而易见”是一个非常危险的词......软件有一个非常不同的“显而易见”概念:-)

标签: c++ code-analysis static-code-analysis cppcheck


【解决方案1】:

我是一名 Cppcheck 开发人员。

Cppcheck 无法检测到这一点并非设计使然。

Cppcheck 当前不使用来自所有函数调用的所有给定参数来评估函数。我们有这方面的票,我希望有一天能修好。会很好的。

如果您使用 Cppcheck,您不应该认为它会检测到所有错误。 Cppcheck 可能无法检测到大多数错误。在我看来,没有任何方法可以检测软件中的所有错误。仅使用 Cppcheck 来检测一些您无法检测到的错误。它在一定程度上减少了错误的数量。

希望您不要太失望,继续使用 Cppcheck。

【讨论】:

  • 抱歉,CppCheck 无法检测到 OP 的问题设计的。 CppCheck 设计 用于生成语言标记流,并应用“模式”来检查标记序列是否存在问题。但是分词器对语言中的类型信息没有真正的理解,因此无法进行任何与“类型”相关的检查。当然,只要有足够的精力,就可以通过处理令牌来添加所有类型的信息,但是到那时你已经拥有了功能齐全的 C++ 前端,而这似乎不在 CppCheck 的野心之内。这个工具在严肃的静态分析中根本走不远。
  • 我对 Cppcheck 并不失望,它是一个很棒的开源项目。我只是不太了解它的局限性。感谢您的解释。
【解决方案2】:

因为目前不支持。

这实际上对编译器来说并不是一个明显的错误。类似的东西

char c[5];
for (int i=0; i<10; ++i)
    c[i] = 0;

更明显,因为它们都在同一个代码中。

类似

#define f(c) { \
    char *p = new char[10];  \
    p[c] = 42; \
}

void g() { 
    f(100); 
} 

更明显,因为 cppcheck 和编译器在实际检查之前就地展开所有宏。

但是,您发布的代码并非微不足道,因为 cppcheck 以及编译器需要该函数内的整个代码并根据参数对其进行评估。如果该功能在视线范围内当然是可能的(跨翻译单元变得非常困难,甚至不可能),但目前,cppcheck 没有该功能。

【讨论】:

    【解决方案3】:

    最新版本的 Cppcheck 1.70 dev 可以检测到这个 bug:

    $ cppcheck test.cpp 
    Checking test.cpp...
    [test.cpp:3]: (error) Array 'p[10]' accessed at index 100, which is out of bounds.
    [test.cpp:4]: (error) Memory leak: p
    

    【讨论】:

    • 此示例是否在同一个文件中具有函数,或者它是否与一个文件中的函数和另一个文件中的函数调用一起使用?
    • 这是一个很好的观点。根据我的测试here,如果代码位于同一文件中,cppcheck 才会检测到缓冲区访问越界问题。
    猜你喜欢
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 2012-11-08
    相关资源
    最近更新 更多