记忆消毒剂
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 可以告诉您哪个函数分配了该值,但仅此而已——通常它会向您显示函数左大括号的源位置。所以你应该仔细检查所有函数的局部变量是否正确初始化。
您不需要任何 Sanitizer 来捕获此错误。编译器可以在编译时找出这个错误(sanitizers 和 valgrind 在 运行 时间工作)。事实上,所有的GCC Clang和ICC都会对这段代码发出警告,如果你打开警告的话。此特定警告由 -Wuninitialized
标志控制。通常,始终使用高警告级别是一种很好的做法。我会推荐以下警告标志组合,尤其是在学习语言时:
-Wall -Wextra -pedantic
如果你得到一些误报,只有在严格检查它们确实是假的之后,你才能禁用特定的警告。没有理由不使用警告标志。一些项目甚至使用 -Werror
标志,将所有警告变成错误。
我正在 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 可以告诉您哪个函数分配了该值,但仅此而已——通常它会向您显示函数左大括号的源位置。所以你应该仔细检查所有函数的局部变量是否正确初始化。
您不需要任何 Sanitizer 来捕获此错误。编译器可以在编译时找出这个错误(sanitizers 和 valgrind 在 运行 时间工作)。事实上,所有的GCC Clang和ICC都会对这段代码发出警告,如果你打开警告的话。此特定警告由 -Wuninitialized
标志控制。通常,始终使用高警告级别是一种很好的做法。我会推荐以下警告标志组合,尤其是在学习语言时:
-Wall -Wextra -pedantic
如果你得到一些误报,只有在严格检查它们确实是假的之后,你才能禁用特定的警告。没有理由不使用警告标志。一些项目甚至使用 -Werror
标志,将所有警告变成错误。