从非初始化的内存中读取每次都会返回不同的答案

Reading from uninitialized memory returns different answers every time

本文关键字:返回 答案 初始化 内存 读取      更新时间:2023-10-16

在尼古拉斯·奥尔莫德(Nicholas Ormrod)在CPPCON 2016上的演讲中,他在Facebook上提到了一个阴险的错误,其中一个单个字节是从一个非传统的(未编写的)页面中读取的,两次第二个读取返回的(非零)值与第一个读取值不同(零)。

他提到他们使用了 jemalloc ,我也认为他们在Linux上运行。Jemalloc的Manpage说,它总是比mmap()更喜欢sbrk()

现在,Jemalloc的唯一mmap()呼叫使用偶尔包含MAP_FIXED的标志MAP_PRIVATE | MAP_ANONYMOUS,尤其是不使用MAP_UNINITIALIZED。这意味着分配时页面总是为零。

此外,即使是带有MADV_DONTNEEDmadvise(),对于匿名映射,也将返回匿名映射的"零填充"页面"零填充页面",我将其读为"零无定位的页面"。

我的问题是:第二读如何返回非零值,导致其错误?

这些家伙提供的解释是完全破坏的(至少在给定的上下文中)。并且该代码无论如何都有不确定的行为。

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

如果data的大小小于(例如,等于size()),则代码由于范围访问而没有定义的行为(并且种族条件变成了MOOT点)。