Динамический загрузчик просто выполняет обычные старые вызовы open(2)
и mmap(2)
, а карта памяти ударяет по inode, пересчитывает так же, как это делает open fd.Так что, если вы выполните обычный трюк с заменой атомарного файла для библиотеки, запишите изменения в новой копии файла, а затем rename(2)
поверх старого имени, все, что будет запущено после этой точки, получит новый индекси новое содержимое, но работающие программы будут продолжать использовать старый инод и старое содержимое.
Если вы измените библиотеку на месте, естественно, любые программы, запущенные после вызова write
, получат ваши изменения.Более интересным вопросом является то, что происходит с процессами, которые уже сопоставили его.Ответ, вероятно, либо «система не позволит вам сделать это», либо «не определено, зависит от деталей реализации кэша страницы».Взглянув на реализацию Linux (это то, что я должен передать): динамический загрузчик glibc использует MAP_DENYWRITE
для всех своих карт общих библиотек, что не задокументировано, но звучит как будто означает «создать этот файл»немодифицируемый, пока существует отображение ".Тем не менее, я не могу найти ничего в исходниках ядра, которое заставляет MAP_DENYWRITE
делать что-либо;это может быть исторический пережиток или что-то подобное.
Он также использует MAP_PRIVATE
.http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html говорит, что «не определено, видны ли изменения в базовом объекте, сделанные после отображения MAP_PRIVATE, через отображение MAP_PRIVATE».Таким образом, вы можете или не сможете изменить образ совместно используемой библиотеки под запущенным процессом, в зависимости от деталей реализации кэша страницы.