我可以引发竞争条件,输出类似于以下内容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(laptop 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:无法分配小字节数”。
我们如何检验这个理论是否正确?
测试期间的
ps aux
运行显示如下行:264173920 是 500 GB 的 50%,其中有 20 个。
内存信息 说:
所以我认为 500GB 就足够了的假设是错误的。
删除
--buffer-size=50%
给出:并且测试完成时 /proc/sys/vm/overcommit_memory=2 没有问题。
总而言之,这解释了大部分情况:运行
sort --buffer-size=50%
吞噬了大量(虚拟)内存,并且由于 overcommit_memory=2 需要虚拟内存可用,因此其他进程没有更多内存可用。使用 overcommit_memory=0 内存不需要可用,因此没有任何失败(因为只使用了少量内存)。
我现在可以通过以下方式引发问题:
然而,让我恼火的是,为什么
sort
不抱怨sort: memory exhausted
或不出现在dmesg
. 这会引导我更快地走向错误。