Como mencionado por @Kusalananda, geralmente as atualizações são feitas removendo o arquivo antigo e criando um novo com o mesmo nome. Isso realmente criará um novo arquivo com um novo inode, deixando o sistema livre para usar o antigo desde que esteja aberto.
Como exemplo simplificado, coisas como
rm /bin/cat
cp /new/version/of/cat /bin/cat
criará um novo arquivo logicamente e funcionará mesmo que cat
esteja em execução. O mesmo vale para bibliotecas. (O acima é um exemplo, não uma maneira robusta de atualizar um arquivo no mundo real.)
Alguém poderia tentar alterar o binário in-place em vez de criar um novo com o mesmo nome. Nesse caso, pelo menos o Linux impede a realização de alterações em um executável em uso:
window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy
No entanto, isso não parece funcionar com bibliotecas carregadas dinamicamente ...
Eu fiz uma cópia de libc.so.6
para teste e preenchai com zeros enquanto estava em uso:
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
linux-vdso.so.1 (0x00007ffcfaf30000)
libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo
Segmentation fault
(Enquanto isso, em outra janela, após o foo
, antes do segfault)
window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000
Realmente não há nada que o programa possa fazer contra isso, já que editei o código on-line de maneira eficaz.
(Isso provavelmente seria dependente do sistema, eu testei no Debian Jessie 8.5, Linux 3.16.7-ckt25-2 + deb8u3. Os sistemas Windows IIRC em particular são ainda mais agressivos em prevenir que arquivos em uso sejam modificados.) / p>
Então eu acho que a resposta é que as atualizações geralmente são feitas de uma maneira que evita qualquer problema, e isso é ajudado pelos componentes internos do sistema de arquivos. Mas (no Linux) não parece haver salvaguardas contra a corrupção de bibliotecas dinâmicas.