简体   繁体   English

Clang 消毒剂未读取未初始化的内存

[英]Clang sanitizers missing a read from uninitialized memory

I have the following code, that I am confident reads from garbage memory, but clang sanitizers do not complain.我有以下代码,我有信心从垃圾内存中读取,但 clang 消毒剂不会抱怨。

Is there something I can do to make them trigger or I should just accept this as limitation/bug?有什么我可以做的事情来触发它们,还是我应该接受它作为限制/错误?

#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;
}

I have tried setting O0 since that sometimes helps, but this time it did not.我曾尝试设置 O0,因为这有时会有所帮助,但这次没有。

godbolt神箭

I am open to using gcc also, but I think gcc does not have memory sanitizer, only asan.我也愿意使用 gcc,但我认为 gcc 没有内存清理器,只有 asan。

From the documentation文档

Uninitialized values occur when stack- or heap-allocated memory is read before it is written.在写入之前读取堆栈或堆分配的内存时,会出现未初始化的值。 MSan detects cases where such values affect program execution. MSan 检测这些值影响程序执行的情况。

MSan is bit-exact: it can track uninitialized bits in a bitfield. MSan 是位精确的:它可以跟踪位域中未初始化的位。 It will tolerate copying of uninitialized memory, and also simple logic and arithmetic operations with it.它将容忍复制未初始化的内存,以及简单的逻辑和算术运算。 In general, MSan silently tracks the spread of uninitialized data in memory, and reports a warning when a code branch is taken (or not taken) depending on an uninitialized value.通常,MSan 会静默跟踪内存中未初始化数据的传播,并在根据未初始化值采用(或未采用)代码分支时报告警告。

That is, in order to minimize false positives, before complaining, clang waits until it is convinced that the uninitialized memory really has an impact on the program execution (takes a different branch, returns a different value from main, etc).也就是说,为了尽量减少误报,在抱怨之前,clang 会等待,直到确信未初始化的内存确实对程序执行有影响(采用不同的分支,从 main 返回不同的值等)。 Copying uninitialized memory around could be innocuous.复制未初始化的内存可能是无害的。

In your particular program, the actual use of the uninitialized value happens in the standard library, possibly even just in the C library, which haven't been instrumented with MSan, so you do not get a warning.在您的特定程序中,未初始化值的实际使用发生在标准库中,甚至可能只是在 C 库中,尚未使用 MSan 进行检测,因此您不会收到警告。

It is critical that you should build all the code in your program (including libraries it uses, in particular, C++ standard library) with MSan.使用 MSan 构建程序中的所有代码(包括它使用的库,特别是 C++ 标准库)至关重要。

This constraint is the main reason why this sanitizer is much less popular than say ASan or UBSan.这种限制是这种消毒剂远不如 ASan 或 UBSan 受欢迎的主要原因。

To come back to this simple program, various static analysis tools can detect the issue, even just g++ -Wall -O will warn, but be aware that false positives are not rare.回到这个简单的程序,各种静态分析工具都可以检测到问题,即使只是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;
      |                            ^~~~~

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM