调试段错误竞争条件

调试段错误竞争条件

我可以引发竞争条件,给出类似于以下内容的输出dmesg

[ 5432.541379] perl[408327]: segfault at 22 ip 0000564eb8af9cc2 sp 00007ffec318cea0 error 6 in perl[564eb8af7000+1a1000]
[ 5432.541402] Code: 83 f8 05 0f 87 cf 00 00 00 0f b7 6b 22 66 81 fd 00 04 77 64 01 ed 8d 7d 05 48 63 ff 48 c1 e7 03 be 01 00 00 00 e8 4e ef ff ff <66> 89 68 22 48 89 c3 66 89 68 24 4c 89 68 08 49 8b 45 00 48 89 03
[ 5432.541638] Core dump to |/usr/share/apport/apport pipe failed
[ 5432.660093] perl[408400]: segfault at 22 ip 00005654e7ec3cc2 sp 00007ffe47312cc0 error 6
[ 5432.660106] perl[408415]: segfault at 22 ip 000055b15d088cc2 sp 00007ffe67124210 error 6
[ 5432.660119]  in perl[5654e7ec1000+1a1000]
[ 5432.660131]  in perl[55b15d086000+1a1000]
[ 5432.660133] Code: 83 f8 05 0f 87 cf 00 00 00 0f b7 6b 22 66 81 fd 00 04 77 64 01 ed 8d 7d 05 48 63 ff 48 c1 e7 03 be 01 00 00 00 e8 4e ef ff ff <66> 89 68 22 48 89 c3 66 89 68 24 4c 89 68 08 49 8b 45 00 48 89 03
[ 5432.660142] Code: 83 f8 05 0f 87 cf 00 00 00 0f b7 6b 22 66 81 fd 00 04 77 64 01 ed 8d 7d 05 48 63 ff 48 c1 e7 03 be 01 00 00 00 e8 4e ef ff ff <66> 89 68 22 48 89 c3 66 89 68 24 4c 89 68 08 49 8b 45 00 48 89 03
[ 5432.660221] sleep[408436]: segfault at 0 ip 00007f18c67150b2 sp 00007ffdaf402820 error 4 in ld-linux-x86-64.so.2[7f18c66fa000+2a000]
[ 5432.660248] Code: 00 00 00 00 00 0f 1f 00 41 55 48 8d 05 50 1e 01 00 49 89 f5 49 89 c9 41 54 49 89 d4 48 89 c2 48 81 ec 18 04 00 00 85 ff 75 53 <41> 80 7d 00 00 48 8d 0d 2b 1e 01 00 4c 8d 05 d4 11 01 00 4c 0f 44
[ 5432.660417] Core dump to |/usr/share/apport/apport pipe failed
[ 5432.660480] Core dump to |/usr/share/apport/apport pipe failed
[ 5432.660543] Core dump to |/usr/share/apport/apport pipe failed
[ 5432.660593] perl[408406]: segfault at 22 ip 000055d5887c3cc2 sp 00007ffcf1af5220 error 6 in perl[55d5887c1000+1a1000]
[ 5432.660629] Code: 83 f8 05 0f 87 cf 00 00 00 0f b7 6b 22 66 81 fd 00 04 77 64 01 ed 8d 7d 05 48 63 ff 48 c1 e7 03 be 01 00 00 00 e8 4e ef ff ff <66> 89 68 22 48 89 c3 66 89 68 24 4c 89 68 08 49 8b 45 00 48 89 03
[ 5432.660888] Core dump to |/usr/share/apport/apport pipe failed
[ 5432.661682] perl[408391]: segfault at 22 ip 00005645d25a8cc2 sp 00007ffc836eb8b0 error 6 in perl[5645d25a6000+1a1000]
[ 5432.661718] Code: 83 f8 05 0f 87 cf 00 00 00 0f b7 6b 22 66 81 fd 00 04 77 64 01 ed 8d 7d 05 48 63 ff 48 c1 e7 03 be 01 00 00 00 e8 4e ef ff ff <66> 89 68 22 48 89 c3 66 89 68 24 4c 89 68 08 49 8b 45 00 48 89 03
[ 5432.661969] Core dump to |/usr/share/apport/apport pipe failed
[ 5433.228271] perl[408513]: segfault at 22 ip 000055bc88f1bcc2 sp 00007ffc31bb1ab0 error 6 in perl[55bc88f19000+1a1000]
[ 5433.228302] Code: 83 f8 05 0f 87 cf 00 00 00 0f b7 6b 22 66 81 fd 00 04 77 64 01 ed 8d 7d 05 48 63 ff 48 c1 e7 03 be 01 00 00 00 e8 4e ef ff ff <66> 89 68 22 48 89 c3 66 89 68 24 4c 89 68 08 49 8b 45 00 48 89 03
[ 5433.306971] perl[408642]: segfault at 22 ip 000055e76e66dcc2 sp 00007ffd37469c20 error 6 in perl[55e76e66b000+1a1000]
[ 5433.306999] Code: 83 f8 05 0f 87 cf 00 00 00 0f b7 6b 22 66 81 fd 00 04 77 64 01 ed 8d 7d 05 48 63 ff 48 c1 e7 03 be 01 00 00 00 e8 4e ef ff ff <66> 89 68 22 48 89 c3 66 89 68 24 4c 89 68 08 49 8b 45 00 48 89 03
[ 5433.307203] Core dump to |/usr/share/apport/apport pipe failed
[ 5433.820922] perl[408816]: segfault at 20 ip 0000557b90fb3463 sp 00007ffcd78bb6f0 error 4 in perl[557b90f88000+1a1000]
[ 5433.820953] Code: 89 df e8 60 9a 0e 00 48 8b 83 e0 00 00 00 48 8b 40 10 48 8b 13 48 85 c0 0f 85 79 ff ff ff e8 44 fc 06 00 48 8b 83 e0 00 00 00 <83> 78 20 00 79 2d 83 7b 30 00 7f 1b 48 8b bb f8 02 00 00 48 83 3f
[ 5433.821219] Core dump to |/usr/share/apport/apport pipe failed

sleep所有程序怎么可能出现段错误?!)

我什至时不时地经历过它会关闭机器上的其他程序。

不幸的是,生成竞争条件的程序相当大:(https://git.savannah.gnu.org/cgit/parallel.git/tree/testsuite/tests-to-run/parallel-local-30s.sh)并且我无法在不消除竞争条件的情况下使其变得更小。

该测试总共产生了超过 10000 个通信perl进程 + 普通 shell 程序 ( sleep, sort, md5sum, bash, paste, wc)。

我已经测试过,这个问题可以在我的笔记本电脑和 512GB 服务器上重现(因此它不是由 RAM 故障、过热或内存不足等原因引起的)。

我该如何调试它并将其变成一份适合相关人员的错误报告?(相关人员是谁?如果两者perl都是sleep段错误,也许我们在内核中遇到了竞争条件?或者在 bash 中?或者 libc?)

编辑

我安装了 FreeBSD12 (Vagrant)。并且测试在 FreeBSD12 中完美运行。这让我认为内核是罪魁祸首。也可能是 Vagrant 以某种方式让 FreeBSD12 不会失败。

笔记本电脑和服务器都运行Ubuntu22.04,所以接下来是尝试运行不同的内核。也许是 Debian 或 CentOS。如果 Ubuntu22.04 在 Vagrant 上失败,我也应该尝试一下。

适用于:FreeBSD12(Vagrant)、Centos8(Vagrant)、Ubuntu20.04(Vagrant)、Ubuntu22.04(笔记本电脑t)、Ubuntu22.10(Vagrant)。

失败:Ubuntu22.04(笔记本电脑a,服务器r)。

我可能找到了罪魁祸首:

echo 2 > /proc/sys/vm/overcommit_memory

如果我这样做:

echo 0 > /proc/sys/vm/overcommit_memory

竞争条件在服务器 r 上消失。

但到底为什么会导致这些错误呢?

编辑

Marcus 认为这可能与内存分配有关,当我看到其他进程在运行过程中死亡时,通常会出现“xmalloc:无法分配少数字节”。

我们如何检验这个理论是否正确?

答案1

ps aux测试期间的运行显示如下行:

tange    1471203  0.0  0.0 264173920 3776 pts/1  T    20:54   0:00 sort --buffer-size=50% -k3r

264173920 是 500 GB 的 50%,其中有 20 个。

记忆信息 说:

$ grep Committ /proc/meminfo
Committed_AS:   5291525876 kB

所以我认为 500GB 就足够了的假设是错误的。

删除--buffer-size=50%给出:

$ grep Committ /proc/meminfo
Committed_AS:   45391448 kB

并且测试完成时没有问题 /proc/sys/vm/overcommit_memory=2。

总而言之,这解释了大部分情况:运行sort --buffer-size=50%会消耗大量(虚拟)内存,并且由于 overcommit_memory=2 需要虚拟内存可用,因此没有更多内存可供其他进程使用。

当 overcommit_memory=0 时,内存不需要可用,因此不会出现任何故障(因为只使用了少量内存)。

我现在可以通过以下方式引发这个问题:

parallel '(seq {};sleep 10) | sort --buffer-size=50%' ::: {1..20}

然而,令我恼火的是,为什么sort不抱怨sort: memory exhausted或出现在dmesg.这会引导我更快地发现错误。

相关内容