0

我有以下代码,我有信心从垃圾内存中读取,但 clang sanitizers 不会抱怨。

我可以做些什么来让它们触发,或者我应该接受它作为限制/错误?

#include <algorithm>
#include <iostream>
#include <vector>

struct B{
    int x;
};

struct D : public B{
    short y;
    D& operator = (const D& other) {
        y = other.y;
        return *this;
    }
};

int main() {
    D var1{4,7},var2;
    var2=var1;
    std::cout << var2.x << "   " << var2.y << std::endl;
}

我曾尝试设置 O0,因为这有时会有所帮助,但这次没有。

神螺栓

我也愿意使用 gcc,但我认为 gcc 没有内存清理器,只有 asan。

4

1 回答 1

2

文档

当堆栈或堆分配的内存在写入之前被读取时,会出现未初始化的值。MSan 检测这些值影响程序执行的情况。

MSan 是位精确的:它可以跟踪位域中未初始化的位。它将容忍复制未初始化的内存,以及简单的逻辑和算术运算。通常,MSan 默默地跟踪未初始化数据在内存中的分布,并根据未初始化的值在执行(或不执行)代码分支时报告警告。

也就是说,为了尽量减少误报,在抱怨之前,clang 会等到确信未初始化的内存确实对程序执行有影响(采用不同的分支,从 main 返回不同的值等)。复制未初始化的内存可能是无害的。

在您的特定程序中,未初始化值的实际使用发生在标准库中,甚至可能只是在尚未使用 MSan 检测的 C 库中,因此您不会收到警告。

使用 MSan 构建程序中的所有代码(包括它使用的库,特别是 C++ 标准库)至关重要。

这种限制是这种消毒剂不如 ASan 或 UBSan 受欢迎的主要原因。

回到这个简单的程序,各种静态分析工具可以检测到问题,甚至g++ -Wall -O会发出警告,但要注意误报并不罕见。

x.cc: In function 'int main()':
x.cc:20:28: warning: 'var2.D::<anonymous>.B::x' is used uninitialized [-Wuninitialized]
   20 |     std::cout << var2.x << "   " << var2.y << std::endl;
      |                            ^~~~~
于 2021-07-30T10:01:40.870 回答