Действительно ли безопасно перекомпилировать исполняемый файл, в то время как это работает?

27
задан HC4 - reinstate Monica 28 July 2010 в 19:09
поделиться

8 ответов

Поскольку это обычный компилятор, который записывает исполняемый файл, давайте проследим его в Linux.

Первое, что нужно знать, это то, что имя файла Linux не относится напрямую к файлу, а скорее к записи каталога, которая не зависит от имени файла. У файла на самом деле не обязательно должно быть имя файла, но если это не так, будет сложно ссылаться на него.

Если процесс использует файл, и вы заменяете или удаляете его, процесс продолжит использовать этот файл через его запись в каталоге. Любой новый процесс, использующий файл или ищущий его, получит новую версию (если вы ее заменили) или не сможет ее найти (если вы ее удалили). После завершения всех процессов со старым файлом он будет удален из файловой системы.

Следовательно, если вы перекомпилируете и создадите новый исполняемый файл с тем же именем, вы не повлияете на запущенный процесс. Он продолжит использовать старый исполняемый файл. Любой новый процесс, который попытается открыть файл, получит новый. Если у вас есть system ("foo"); в цикле, каждый раз, когда он его выполняет, он сразу видит, что означает имя файла foo.

Windows по-другому обрабатывает файлы. В общем, если есть процесс, использующий файл, файл заблокирован и не может быть удален или заменен.

30
ответ дан 28 November 2019 в 05:10
поделиться

Это зависит. Из того, что я испытал, в Linux вы все равно можете запустить программу, если удалите ее (и она не слишком большая). Но я не думаю, что это определенное поведение.

Что касается цикла, то в зависимости от того, как вы вызываете исполняемый файл, вы, скорее всего, закончите сбоем своего скрипта, когда он выполнит программу, написанную только наполовину.

0
ответ дан Wayne Werner 28 November 2019 в 05:10
поделиться

В Windows вы не можете удалить заблокированный файл, но большинство людей не знают, что вы можете переместить или переименовать запущенный exe.

Чтобы вы могли

  • переместить старый исполняемый файл во временную директорию на том же диске
  • запланировать его удаление при следующей перезагрузке: MoveFileEx (name, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
  • переместите новый exe в свое место.

Старая программа продолжит работу, но новые процессы будут использовать новый файл.

6
ответ дан 28 November 2019 в 05:10
поделиться

Это зависит от обстоятельств.

Если ОС считывает исполняемый файл целиком в память и не обращается к образу диска, то да, вы можете перекомпилировать его, пока он «использовался».

На практике это происходит не всегда. Если ОС сохраняет дескриптор файла открытым (как это делает Windows) в исполняемом файле, это предотвратит удаление и / или перезапись файла.

В Linux / Unix можно перезаписать «используемый» файл. См. Ответ Дэвида Торнли для подробного объяснения.

8
ответ дан 28 November 2019 в 05:10
поделиться

Я полагаю, это не позволит вам заменить файл, поскольку Windows заблокировала его, пока он использовался.

0
ответ дан 28 November 2019 в 05:10
поделиться

Исполняемый файл может полностью загружаться в память при запуске, однако, если он достаточно большой и работает достаточно долго, ОС может решить заменить некоторые неиспользуемые его части.

Поскольку ОС предполагает, что файл программы все еще существует, нет причин фактически записывать эти блоки памяти в файл подкачки. Так что они просто аннулируются и используются повторно. Если программе снова нужны эти страницы, ОС загружает их из исполняемого файла.

В Windows это на самом деле происходит автоматически, поскольку загруженный модуль является файлом с отображением памяти. Это также означает, что файл заблокирован во время выполнения, и вы не сможете легко его перезаписать.

Не уверен насчет Linux, но IIRC выполняет подкачку таким же образом.

-1
ответ дан 28 November 2019 в 05:10
поделиться

В Windows нельзя, если исполняемый файл все еще запущен, файл будет заблокирован. Если exe на самом деле не запущен, новые запуски должны подхватить новый, в зависимости от того, как ваш скрипт закодирован, среди прочего.

Я ничего не знаю о Linux.

0
ответ дан 28 November 2019 в 05:10
поделиться

В Linux исполняемые файлы загружаются в память по мере необходимости. Исполняемый файл на диске становится резервным хранилищем для приложения. Это означает, что вы не можете изменять исполняемый файл на диске, иначе вы повлияете на работающее приложение. Если вы попытаетесь открыть(2) исполняемый файл для записи, вы получите ошибку ETXTBSY (Text file busy) (проверьте страницу руководства для open(2)).

Как уже говорили другие, вы можете удалить файл из файловой системы (unlink(2)), и ядро сохранит ссылку на него и не будет удалять его с диска, пока не останется ссылок (когда процесс завершается, он освобождает свою ссылку на файл). Это означает, что вы можете эффективно "перезаписать" используемый исполняемый файл, сначала удалив его, а затем создав новый файл с тем же именем, что и старый.

Итак, все сводится к тому, как компилятор создает исполняемый файл при "перезаписи" существующего файла. Если он просто открывает файл для записи и усекает его (O_WRONLY|O_CREAT|O_TRUNC), то произойдет ошибка ETXTBSY. Если сначала удалить существующий выходной файл и создать новый, он будет работать без ошибок.

6
ответ дан 28 November 2019 в 05:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: