【问题标题】:Memory Sanitizer记忆消毒剂
【发布时间】:2015-12-07 18:54:55
【问题描述】:

我在 Ubuntu 14.04 上使用带有 Clang 3.7.0 的 Memory Sanitizer。以下代码可以完美运行:

#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 未初始化的事实吗?

感谢您的帮助。

【问题讨论】:

  • 尝试将 ans 更改为 char*!
  • 由于明显缺乏任何研究而被否决。
  • 我很惊讶编译器本身没有抱怨。我知道编译器不能通过静态分析来捕捉每一个这样的情况,但它应该能够捕捉到这样的简单化。
  • @AdrianMcCarthy GCC 和 Clang do 抱怨 if 你打开警告(例如使用-Wall,这个特定的由控制-Wuninitialized),这是 OP 没有做的。
  • 你试过 -fsanitize=address 吗?

标签: c++ sanitizer msan


【解决方案1】:

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

【讨论】:

  • 谢谢。我现在明白我的问题很愚蠢,因为这种检查可以静态进行。
【解决方案2】:

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

-Wall -Wextra -pedantic

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

【讨论】:

    【解决方案3】:

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

    Valgrind 文档:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-06
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      • 2021-04-02
      • 2021-01-23
      • 2017-09-17
      相关资源
      最近更新 更多