【问题标题】:Clang sanitizers missing a read from uninitialized memoryClang sanitizers 缺少未初始化内存的读取
【发布时间】:2021-10-05 03:26:14
【问题描述】:

我有以下代码,我有信心从垃圾内存中读取,但 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,因为这有时会有所帮助,但这次没有。

godbolt

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

【问题讨论】:

  • Visual Studio 中 clang-cl 的静态分析器给出了以下信息:警告 GDEC5F24A:第一个函数调用参数是一个未初始化的值 [clang-analyzer-core.CallAndMessage]。不确定最后一点是否有帮助?
  • gcc with -Wall 和 -O 或更高版本表示“警告:'var2.D::.B::x' 未初始化”。
  • @MarcGlisse 很有趣,我不知道 GCC 警告取决于优化级别... + gcc 静态分析的怪异比 sanitizer 更好... :)
  • @AdrianMole 很有趣,是否有一个 clang 标志可以做到这一点,或者我需要为此使用 scan-build?
  • clang 的内存清理器在它认为的用途方面似乎非常严格,它不会对 int x;volatile int y=x+1; 发出警告(它只会传播 y 未初始化的信息),但对 int x; volatile int y=x?x:x; 会发出警告...使用 iostream,实际使用可能无论如何都在(未检测的)库中。

标签: c++ clang sanitizer memory-sanitizer


【解决方案1】:

来自the documentation

当堆栈或堆分配的内存被分配时,会出现未初始化的值 在写入之前阅读。 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;
      |                            ^~~~~

【讨论】:

  • gcc 警告中的下划线是假的 :-(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多