AddressSanitizer 随机抛出 SIGSEGV,没有任何解释

Leo*_*ard 8 c++ linux gdb segmentation-fault address-sanitizer

项目

\n

我目前正在开发一个 C++ 游戏项目。\n我编译每个源文件以-g3 -std=c++2a -Wall ... -fsanitize=address -fsanitize=leak检查泄漏和段错误

\n

主要问题

\n

问题是,asan(地址或泄漏)随机地(五分之一)在没有任何诊断的情况下使用 SIGSEGV 到达主程序之前终止程序。

\n
AddressSanitizer:DEADLYSIGNAL\n=================================================================\n==28573==ERROR: AddressSanitizer: SEGV on unknown address 0x625505a4ce68 (pc 0x7cc52585f38f bp 0x000000000000 sp 0x7fff63949020 T0)\n==28573==The signal is caused by a READ memory access.\nAddressSanitizer:DEADLYSIGNAL\nAddressSanitizer: nested bug in the same thread, aborting.\n
Run Code Online (Sandbox Code Playgroud)\n

SEGV 发生的地址总是不同的,PC 也是如此(最后 3 位数字除外,分别为 e68、38f)

\n

它运行的系统

\n

我的机器是Arch Linux 6.7.0-arch3-1并且我正在使用g++ (GCC) 13.2.1 20230801, GNU gdb (GDB) 13.2,这是撰写本文时存储库上的最新版本

\n

我尝试过的

\n

我不知道如何找出这个错误,也不知道是什么原因造成的。

\n

在代码中

\n

我确信问题发生在 main 之前,因为打印某些内容(使用 cout 或 printf)没有效果,与使用信号处理程序相同,signal(SIGSEGV, &handle);

\n

阿三是其中的一部分

\n

没有asan,SEGV 就不会发生。(我已经尝试了50~次,每次程序都正确启动)

\n

数据库

\n

在关闭 asan 和 ASLR 编译的程序中使用 gdb 会导致 SIGSEGV 和自动捕获

\n

问题的汇编指令

\n

鉴于问题发生的奇怪地址模式,我尝试在任何$pc以 38f ( watch ((size_t)$pc & 0xfff) == 0x38f) 结尾的地址上使用观察点。\n观察点有效,有问题的地址包含在 libc 函数(do_lookup_x或类似函数)中,该函数似乎被调用了数千次,在主要开始之前,使这种方式的调试几乎成为一场噩梦。

\n

问题

\n

我想问是否有人知道如何从 asan、gdb 或任何其他工具获取更多信息,因为目前我没有足够的信息来知道问题发生在哪里,或者即使问题是我的或不。

\n
\n

更新

\n

@marekR 和 @eljay 建议与某些 glibc 函数/名称发生某种符号冲突。我的大多数定义都包含在名称空间中(因此名称也被破坏),唯一足以与其他名称冲突的通用函数是init()loop()terminate()。更改名字并没有解决问题

\n

按照 @\xc3\x96\xc3\xb6Tiib 建议,我用 测试了我的 git 历史记录git bisect,这个问题自 2019 年第一次提交以来就出现了,这意味着它可能一直没有被注意到,(我是唯一一个)正在从事这个项目,但似乎不太可能),这是我的机器本地因素的组合,或者其他因素

\n

Leo*_*ard 0

感谢@EmployedRussian,我能够追踪到错误的根源。由于这是这个问题的重点,我将关闭这篇文章。

我会尝试自己解决该错误,如果我没有能力,我会在 asan 上打开另一个问题/错误跟踪器。

无论如何,我感谢你对我的帮助。

对于任何感兴趣的人,用 编译二进制文件并在-fsanitize=address下运行它可能会导致 SIGSEGV,gdb 应该自动捕获它。gdbset disable-radomization off

我认为这个问题已经结束了。