记忆消毒剂

Memory Sanitizer

我正在 Ubuntu 14.04 上用 Clang 3.7.0 玩内存消毒器。以下代码确实可以完美运行:

#include <cstdio>

int main() {
  double ans;
  printf("Hello World: %f\n", ans);

  return 0;
}

编译时

 clang++ -g -O1 -fsanitize=memory -fsanitize-memory-track-origins=2 -fomit-frame-pointer sanitize.cpp -o sanitize

我期待一个错误。 Memory Sanitizer 没有捕捉到 ans 未初始化的事实吗?

感谢您的帮助。

从 clang sanitizer 文档可以清楚地看出,它只处理动态分配内存中的未初始化内存读取。自动记忆不是消毒剂检查的一部分。

Valgrind memcheck 可以作为检测未初始化堆栈值的选项。

Valgrind 文档:

对于源自堆块的未初始化值,Memcheck 会显示块的分配位置。对于源自堆栈分配的未初始化值,Memcheck 可以告诉您哪个函数分配了该值,但仅此而已——通常它会向您显示函数左大括号的源位置。所以你应该仔细检查所有函数的局部变量是否正确初始化。

参考: http://valgrind.org/docs/manual/mc-manual.html

您不需要任何 Sanitizer 来捕获此错误。编译器可以在编译时找出这个错误(sanitizers 和 valgrind 在 运行 时间工作)。事实上,所有的GCC Clang和ICC都会对这段代码发出警告,如果你打开警告的话。此特定警告由 -Wuninitialized 标志控制。通常,始终使用高警告级别是一种很好的做法。我会推荐以下警告标志组合,尤其是在学习语言时:

-Wall -Wextra -pedantic

如果你得到一些误报,只有在严格检查它们确实是假的之后,你才能禁用特定的警告。没有理由不使用警告标志。一些项目甚至使用 -Werror 标志,将所有警告变成错误。