问题所在

最近,在Linux内核6.6.6和更高版本上,发现thread sanitizer will always lead to this error:

FATAL: ThreadSanitizer: unexpected memory mapping 0x5c9bd4d2b000-0x5c9bd4d4b000

我可以通过用C编写一个Hello World示例来重现这一点

#include <stdio.h>

int main(void)
{
    printf("Hello, World!\n");
}

并在Arch Linux(Kernel 6.7.0)上使用TSan+编译它,并使用:

clang -o play -fsanitize=thread -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer src/play.c
./play

这将产生上述错误(具有不同的存储器地址).

根据GitHub的问题,这也会发生在只定义空的main()函数的C++文件中.

问题是

你有什么 Select 来处理这件事吗?

我最近才开始更深入地研究低级操作,以我目前的知识水平,我只能勉强使用use种线程消毒剂.ASLR(似乎是问题的原因)对我来说完全陌生,操纵它的 Select 和后果是什么.

GitHub问题提到了两种可能的解决方法:

  1. 禁用ASLR(我只找到this SO question for this个)
  2. 通过sudo sysctl vm.mmap_rnd_bits=30%降低ASLR

我已经try 了2.并按照描述重新编译+运行了该示例,这并没有解决问题.

我很犹豫是否按照1禁用ASLR,因为我不知道这意味着什么,也不知道如何"撤销"这一改变.

还有什么其他一般的 Select 来解决这个问题呢?

推荐答案

在本例中,sudo sysctl vm.mmap_rnd_bits=30确实足够了,但需要比Arch-Linux默认提供的clang版本更新的clang版本. compose 本文时的版本(16.0.6)源自June 2023.

not包含从November 2023开始的修复,该修复允许mmap_rnd_bits值为30.

然而,至少在Arch Linux上,您可以将此值设置为28,在这一点上,它应该会再次使用16.0.6(尽管这似乎意味着降低了系统的安全性(?),它肯定比完全关闭ASLR要好).

您可以将其设置为28到sudo sysctl vm.mmap_rnd_bits=28(判断通过sudo sysctl vm.mmap_rnd_bits的值),这应该会使TSan再次工作.

C++相关问答推荐

为指针 struct 创建宏

如何将FileFilter添加到FileDialog GTK 4

如何将已分配的数组(运行时已知的大小)放入 struct 中?

Malloc(sizeof(char[Length]))是否不正确?

为什么GCC C23中的关键字FALSE不是整数常量表达式?

为什么该函数不将参数值保存到数据 struct 中?

getline()从c中的外部函数传递指针时输出null

C++中PUTS函数的返回值

如何逐位读取二进制文件?

从另一个宏函数调用C宏

为什么我的旧式&q;函数在传递浮点数时会打印2?

如何在不更改格式说明符的情况下同时支持双精度和长双精度?

正在try 理解C++中的`正在释放的指针未被分配‘错误

Dlsym()的手册页解决方法仍然容易出错?

将不同类型的指针传递给函数(C)

即使客户端不发送数据,也会发生UNIX套接字读取

为什么 int32_t 和 int16_t 在 printf 输出中具有相同的位数?

UEFI 应用程序中的计时器回调仅在 AMI BIOS 中挂起

C23 中是否有 __attribute__((nonnull)) 的等效项?

Zig 中 C 的system函数的惯用替代方案