从未初始化的内存读取返回不同的答案每次

在Nicholas Ormrod在CppCon 2016上的讲话中,他提到了Facebook上一个隐藏的bug,其中一个字节从未初始化(未写入)页面被两次读取,使得第二次读取返回(非零)值不同的情况从第一个读取的值(零)。

他提到他们使用的是jemalloc , 我也假定他们在Linux上运行。 jemalloc的manpage说它总是比sbrk()更喜欢mmap() sbrk()

现在, jemalloc唯一的mmap()调用使用标志MAP_PRIVATE | MAP_ANONYMOUS MAP_PRIVATE | MAP_ANONYMOUS偶尔包含MAP_FIXED ,特别是它不使用MAP_UNINITIALIZED 。 这意味着页面在分配时总是被初始化 。

此外,对于匿名映射,即使madvise()MADV_DONTNEED也会为匿名映射返回“零填充点播页面” ,我将其称为“零初始化页面”。

我的问题是:第二次读取会返回非零值,导致错误?

无论这个家伙提供什么解释,都是完全失败的(至少在给定的情况下)。 而且代码有不确定的行为。

如果data指向至少以size() + 1大小分配的块,则代码由于竞争条件而具有未定义的行为(他提到之前使用线程)。

如果data的大小小于这个值(例如等于size() ),那么由于出界限制访问(并且争用条件成为一个争议点),代码具有未定义的行为。