Исполняемые объектные файлы и виртуальная память - PullRequest
0 голосов
/ 27 ноября 2018

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

скажем, у нас есть исполняемый объектный файл a.out хранится на жестком диске, и, скажем, изначально a.out имеет секцию .data с глобальной переменной со значением 2018. Когда запускается загрузчик, он выделяет непрерывный кусок меток виртуальных страницони недействительны (то есть не кэшированы) и указывают свои записи в таблице страниц на соответствующие места в a.out.Загрузчик никогда не копирует данные с диска в память.Данные вводятся автоматически и по запросу системой виртуальной памяти при первом обращении к каждой странице.

Мой вопрос: предположим, что программа меняет значение глобальной переменной с 2018 на 2019 во время выполнения иПохоже, что виртуальная страница, содержащая глобальную переменную, в конечном итоге перейдет на диск, что означает, что в разделе .data глобальная переменная теперь равна 2019, поэтому мы изменяем исполняемый объектный файл, который не являетсядолжен быть изменен?в противном случае мы получим новое значение каждый раз, когда закончим и снова запустим программу?

1 Ответ

0 голосов
/ 27 ноября 2018

В общем случае (не специально для Linux) ...

Когда запускается исполняемый файл, ОС (ядро) создает виртуальное адресное пространство и (изначально пустой) процесс, а также проверяет исполняемый файл.заголовок.Заголовок исполняемого файла описывает «разделы» (например, .text, .rodata, .data, .bss и т. Д.), Где каждый раздел имеет разные атрибуты - если содержимое раздела следует поместить в виртуальное адресное пространство илинет (например, таблица символов или что-то, что не используется во время выполнения), если содержимое является частью файла или нет (например, .bss), и если область должна быть исполняемой, только для чтения или для чтения/write.

Обычно (используемые части) исполняемого файла кэшируются виртуальной файловой системой;и части файла, которые уже находятся в кэше VFS, могут быть сопоставлены (как «копировать при записи») в виртуальное адресное пространство нового процесса.Для частей, которых еще нет в кэше VFS, эти части файла могут быть сопоставлены как «нужная загрузка» в виртуальное адресное пространство нового процесса.

Затем процесс запускается (с учетом времени ЦП).

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

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

Если процесс выполняет запись в данные со страницы, которая еще не была загружена;ОС (ядро) объединяет обе предыдущие вещи (извлекает исходную страницу с диска в кэш VFS, создает копию, отображает виртуальное адресное пространство процесса «копия в процесс»).

Если ОС начинаетне хватает свободной оперативной памяти;затем:

  • страниц файловых данных, которые находятся в кеше VFS, но не переданы как «копирование при записи» любому процессу, могут быть освобождены в VFS без выполнения каких-либо других действий.При следующем использовании файла эти страницы будут извлечены из файла на диске в кэш VFS.

  • страниц данных файла, которые находятся в кеше VFS и также передаются как «копия».при записи "с любым процессом может быть освобожден в VFS, а копии в любом / всех процессах помечены как" еще не получены ".В следующий раз, когда файл будет использован (в том числе, когда процесс получит доступ к «еще не извлеченным» страницам), эти страницы будут извлечены из файла на диске в кэш VFS, а затем сопоставлены как «копировать при записи» в процессе / э).

  • страниц данных, которые были изменены (либо потому, что они изначально были «копированы при записи», но скопированы, либо потому, что они вообще не были частью исполняемого файла -например, секцию .bss, пространство кучи исполняемого файла и т. д.) можно сохранить в пространство подкачки, а затем освободить.Когда процесс снова получит доступ к страницам, они будут извлечены из пространства подкачки.

Примечание. Если исполняемый файл хранится на ненадежном носителе (например, потенциально поцарапанном компакт-диске), ОС «умнее среднего» может загрузить весь исполняемый файл в кэш VFS и / или в пространство подкачки;потому что нет никакого вменяемого способа обрабатывать «ошибку чтения из файла, отображенного в память», пока процесс использует этот файл, не вызывая сбой процесса (например, SIGSEGV) и делая его похожим на исполняемый файл с ошибками, когда его нет, и потомуэто повышает надежность (потому что вы зависите от более надежного свопинга, а не от менее надежного поцарапанного CD).Также;если ОС защищает от повреждения файлов или вредоносного ПО (например, имеет встроенную CRC или цифровую подпись в исполняемые файлы), то ОС может (должна) загрузить все в память (кэш VFS), чтобы проверить CRC или цифровую подпись, прежде чем разрешить выполнение исполняемого файла.и (для защищенных систем, в случае, если файл на диске изменен во время работы исполняемого файла), при освобождении ОЗУ могут храниться неизмененные страницы в «более надежном» пространстве подкачки (так же, как если бы страница была изменена), чтобы избежатьизвлечение данных из исходного «менее надежного» файла (отчасти потому, что вы не хотите выполнять полную проверку цифровой подписи каждый раз, когда из файла загружается страница).

Мой вопрос:Предположим, что программа изменяет значение глобальной переменной с 2018 на 2019 во время выполнения, и кажется, что виртуальная страница, содержащая глобальную переменную, в конечном итоге будет выгружена на диск, что означает, что раздел .data имеет глобальную переменную, равную 2019.Теперь мы изменим исполняемый объектфайл, который не должен быть изменен?

Страница, содержащая 2018, будет начинаться как «не извлечена», затем (при обращении к ней) загружается в кэш VFS и отображается в процессе как «копия».на записи ".В любой из этих точек ОС может освободить память и извлечь данные (которые не были изменены) из исполняемого файла на диске, если это потребуется снова.

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

...