Irá sobrescrever para um arquivo executável afeta um processo que está executando o arquivo executável original?

4

Quando um arquivo executável é executado em um processo, se o arquivo executável for sobrescrito ou excluído e recriado por reinstalação, o processo executará novamente o novo arquivo executável?

A resposta para a pergunta depende de

  • se o executável é executado como um serviço / daemon no processo ou não?

  • o sistema operativo, e. Linux, Unix, ...?

  • se a reinstalação é de um arquivo de instalação (por exemplo, deb no Ubuntu, msi no Windows) ou da criação de seu código-fonte?

Aqui estão alguns exemplos:

  • No Ubuntu, quando um processo executa um arquivo executável e quando eu sobrescrevo o arquivo executável, pela reinstalação manual via configure , make e make install em seu código-fonte, o processo continua para executar o arquivo executável original, em vez do novo arquivo executável.

  • Ouvi dizer que no Windwos 10, quando um processo executa um arquivo executável como um serviço, se reinstalarmos o arquivo executável por meio do arquivo msi do instalador, o processo do serviço será reiniciado para executar o novo arquivo executável . É o mesmo caso ou similar para instalação de arquivos .deb no Ubuntu ou Debian?

Obrigado.

    
por Tim 24.03.2017 / 00:49

3 respostas

4

Depende do kernel e do tipo de executável. Não depende de como o executável foi iniciado ou instalado.

No Linux:

  • Para executáveis nativos (ou seja, binários contendo código de máquina, executados diretamente pelo kernel), um executável não pode ser modificado durante a execução.

    $ cp /bin/sleep .
    $ ./sleep 999999 &
    $ echo >sleep
    sh: 1: cannot create sleep: Text file busy
    

    É possível remover o executável (isto é, desvinculá-lo) e criar um novo no mesmo caminho. Como qualquer outro caso em que um arquivo é removido enquanto ainda está aberto, a remoção do executável não afeta o processo em execução e, na verdade, não o remove do disco até que o arquivo não esteja mais em uso, ou seja, até que todas as instâncias em execução sejam executadas. a saída do programa.

  • Para scripts (começando com #! ), o arquivo de script pode ser modificado enquanto o programa está em execução. Se isso afeta o programa depende de como o interpretador lê o script. Se ele ler todo o script em sua própria memória antes de começar a executar, a execução não será afetada. Se o interpretador ler o script sob demanda, a execução poderá ser afetada; algumas implementações de sh fazem isso.

Muitos outros sistemas Unix se comportam dessa maneira, mas não todos. As versões antigas do IIRC do Solaris permitem modificar um executável nativo, o que geralmente faz com que ele falhe. Algumas variantes Unix, incluindo HP / UX, nem permitem a remoção de um executável nativo que está sendo executado atualmente.

A maioria dos programas de instalação de software tem o cuidado de remover um executável existente antes de colocar um novo no lugar, ao invés de sobrescrever o binário existente. Por exemplo. fazer

rm /bin/target
cp target /bin

em vez de apenas cp target /bin . O comando install shell faz as coisas desta maneira. Isso não é ideal, porque se alguém tentar executar /bin/target enquanto o processo cp estiver em execução, ele receberá um programa corrompido. É melhor copiar o arquivo para um nome temporário e depois renomeá-lo para o nome final. Renomear um arquivo (ou seja, movê-lo dentro do mesmo diretório ou, mais geralmente, movê-lo dentro do mesmo sistema de arquivos) remove o arquivo de destino anterior, se houver. É assim que dpkg funciona, por exemplo.

cp target /bin/target.tmp
mv /bin/target.tmp /bin/target
    
por 25.03.2017 / 02:24
3

Você pode experimentar você mesmo:

$ cp /usr/bin/sleep /tmp/sleep
$ /tmp/sleep 20 &
$ truncate -s 1 /tmp/sleep
truncate: cannot open '/tmp/sleep' for writing: Text file busy

O sistema não permite alterar um binário em execução. No entanto, você pode desvincular o arquivo e alterá-lo:

$ /tmp/sleep 20 &
$ rm /tmp/sleep
$ cp /usr/bin/ls /tmp/sleep
$ [2]-  Done                    /tmp/sleep 20

Note que, para scripts de shell, o kernel não protege o script, pois o binário ocupado é / bin / bash, por exemplo. Você não deve sobrescrever o arquivo de script de shell, mas pode removê-lo e substituí-lo por um novo.

Quanto à instalação de pacotes atualizados, depende do empacotador se um daemon em execução será reiniciado ou não. Eu não sei se existe uma convenção, mas eu olhei alguns exemplos de scripts rpm no meu sistema Fedora e eles parecem reiniciar na atualização. Por exemplo,

$ rpm --scripts -qf /usr/sbin/xinetd 
...
postuninstall scriptlet (using /bin/sh):
...
if [ $1 -ge 1 ] ; then 
    # Package upgrade, not uninstall 
    systemctl try-restart xinetd.service >/dev/null 2>&1 || : 
fi

Um upgrade de rpm -U de um pacote executará os novos scriptlets de pré e pós-instalação, depois os antigos scriptlets de pré e pós-desinstalação. Como visto acima, o postuninstall fará uma reinicialização do serviço systemd.

Nos comentários, confira também este answer em bibliotecas compartilhadas, e observe como a mudança de scripts interpretados depende muito de como o interpretador armazena em buffer ou releia o arquivo, ou o recompila para um novo arquivo em tempo real.

    
por 24.03.2017 / 08:35
1

Will overwriting to an executable file affect a process which is running the original executable file?

normalmente não, meu entendimento é que quando o kernel bifurca e executa o novo processo, o executável (que contém um programa) é lido e carregado na memória.
O arquivo subjacente geralmente não é mais necessário, pelo menos até a próxima vez em que o arquivo for lido para outro processo.
É por isso que você precisa reiniciar o computador depois que uma atualização substituir o arquivo subjacente de um programa ou biblioteca do sistema - você não pode "afetar o processo em execução" (isto é, substituir) com uma nova versão foi lido de um arquivo atualizado.
A única maneira de obter a nova funcionalidade atualizada é parar o processo em execução e recarregá-lo a partir do novo arquivo, mas no caso de programas do sistema ou do próprio kernel, o programa não pode ser encerrado, como por exemplo com um navegador. E assim todo o sistema tem que ser derrubado para ler o novo arquivo - atualizado.

    
por 24.03.2017 / 06:30