Posso provocar uma condição de corrida que forneça uma saída semelhante a esta em 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
(Como sleep
todos os programas podem segfault?!)
Já experimentei de vez em quando que ele desativa outros programas na máquina.
Infelizmente, o programa para gerar a condição de corrida é bastante grande: ( https://git.savannah.gnu.org/cgit/parallel.git/tree/testsuite/tests-to-run/parallel-local-30s.sh ) e Não posso torná-lo muito menor sem que a condição de corrida desapareça.
O teste gera no total mais de 10.000 perl
processos de comunicação + programas shell comuns ( sleep
, sort
, md5sum
, bash
, paste
, wc
).
Eu testei que esse problema pode ser reproduzido em meu laptop e meu servidor de 512 GB (portanto, não é causado por, digamos, RAM ruim, superaquecimento ou falta de memória).
Como faço para depurar isso e transformá-lo em um relatório de bug decente para as pessoas relevantes? (E quem são as pessoas relevantes? Se ambos perl
e sleep
segfault, talvez estejamos assumindo uma condição de corrida no kernel? Ou no bash? Ou libc?)
Editar
Eu instalei o FreeBSD12 (Vagrant). E o teste roda perfeitamente no FreeBSD12. Isso me faz pensar que o kernel é o culpado. Também pode ser que o Vagrant de alguma forma faça o FreeBSD12 não falhar.
Tanto o laptop quanto o servidor executam o Ubuntu22.04, portanto, tente executar um kernel diferente. Talvez Debian ou CentOS. Também devo tentar se o Ubuntu22.04 falhar no Vagrant.
Funciona: FreeBSD12(Vagrant), Centos8(Vagrant), Ubuntu20.04(Vagrant), Ubuntu22.04(laptop t), Ubuntu22.10(Vagrant).
Falha: Ubuntu22.04(laptop a, servidor r).
Eu poderia ter encontrado o culpado:
echo 2 > /proc/sys/vm/overcommit_memory
Se eu fizer isso:
echo 0 > /proc/sys/vm/overcommit_memory
a condição de corrida desaparece no servidor r.
Mas por que diabos isso causaria esses erros?
Editar
Marcus sugere que pode ter a ver com a alocação de memória e, quando vejo outros processos morrerem durante a execução, geralmente é com "xmalloc: não é possível alocar pequenos números de bytes".
Como testamos se essa teoria está correta?
Uma
ps aux
execução durante o teste revela linhas como:264173920 é 50% de 500 GB, e há 20 deles.
meminfo diz:
Portanto, minha suposição de que 500 GB seriam suficientes estava errada.
A remoção
--buffer-size=50%
dá:e o teste é concluído sem problemas com /proc/sys/vm/overcommit_memory=2.
Em suma, isso explica a maior parte da situação: a execução
sort --buffer-size=50%
consome muita memória (virtual) e, como overcommit_memory=2 requer que a memória virtual esteja disponível, não há mais memória disponível para outros processos.Com overcommit_memory=0, a memória não precisa estar disponível e, portanto, nada falha (já que apenas uma pequena quantidade da memória é usada).
Agora posso provocar o problema com:
O que me incomoda, porém, é por que
sort
não está reclamandosort: memory exhausted
ou aparecendo emdmesg
. Isso teria me guiado muito mais rapidamente em direção ao erro.