使clang的Memory Sanitizer报告统一变量使用而无需决定分支

时间:2018-07-04 16:17:03

标签: c++ memory clang llvm address-sanitizer

我正在尝试使用Clang 6.0的Memory Sanitizer(MSan)。 使用

编译代码
clang++ memsans.cpp -std=c++14 -o memsans -g -fsanitize=memory -fno-omit-frame-pointer -Weverything

在Ubuntu 18.04上。按照MSan documentation

  

它可以容忍未初始化内存的复制,并且也很简单   逻辑和算术运算。通常,MemorySanitizer   静默地跟踪未初始化数据在内存中的传播,并   当采用(或不采用)代码分支时,将报告警告   未初始化的值。

因此以下代码不会产生任何错误

#include <iostream>

class Test {
public:
    int x;
};

int main() {
    Test t;
    std::cout << t.x;
    std::cout << std::endl;
    return 0;
}

但这会

#include <iostream>

class Test {
public:
    int x;
};

int main() {
    Test t;
    if(t.x) {
        std::cout << t.x;
    }
    std::cout << std::endl;
    return 0;
}

理想情况下,人们希望这两个代码示例都产生某种错误,因为从第一个正在打印它的意义上讲,这两个示例都“使用”了未初始化的变量。该代码是一个很小的测试代码,因此第一个代码中的错误是显而易见的,但是,如果它是一个较大的代码库,并且具有类似的错误,MSan将会完全错过这一点。是否有任何黑客可以迫使MSan报告这种类型的错误?

1 个答案:

答案 0 :(得分:0)

听起来您的C ++库不是用MSan构建的。与ASan和UBSan不同,MSan要求整个程序都在启用msan的情况下构建。将其视为具有不同的ABI,您不应链接使用不同的msan设置构建的两个程序。一个例外是libc,msan为此添加了“拦截器”以使其起作用。

如果您编写自己的代码,并希望通过报告错误(通常不会产生msan的错误)来与msan集成(例如,在创建副本但您知道数据需要初始化的函数中),则可以使用从msan_interface.h文件__msan_check_mem_is_initialized:https://github.com/llvm-mirror/compiler-rt/blob/master/include/sanitizer/msan_interface.h