LINUX.ORG.RU

В какое загрузится, в том и работает.

В бинарнике приложения указаны имена so. При запуске бинарника система размещает их в том же адресном пространстве и связывает все точки вызова функций между модулями.

Также можно грузить so-шки прямо из кода при помощи dlopen().

wandrien ★★
()

В ВАП каждого работающего с ними процесса, т.к. динамическое связывание как раз предполагает создание ссылок на so и их символы, на привязыанные символы можно посмотреть через например objdump -R /bin/bash

AKonia ★★
()
Последнее исправление: AKonia (всего исправлений: 2)

Тут фишка в использовании виртуальной памяти, код SO загружается по некому физическому адресу и эти страницы мапятся в виртуальное пространство процессов которые хотят эту SO использовать

sparks ★★★★
()

разные процессы могут совместно использовать загруженные модули

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

X512 ★★★★★
()
Ответ на: комментарий от X512

Не загружаются они заново, читайте хотя бы у Дреппера статью о том как нужно so’шки писать или у Керриска тоже было немного по дин библиотекам.

AKonia ★★
()
Последнее исправление: AKonia (всего исправлений: 2)
Ответ на: комментарий от AKonia

Логически они именно «загружаются заново» в каждое адресное пространство.

То, что там под капотом маппинг памяти — деталь реализации.

wandrien ★★
()
Ответ на: комментарий от AKonia

Не не загружаются заново

Вы путаете с общей read only memory.

читайте хотя бы у Дреппера статью о том как нужно so’шки писать или у Керриска тоже было немного.

Это про всякие PIC которые позволяют увеличить увеличить повторное использование памяти для кода.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от X512

Просто помню что дреппер писал, что в старом линуксе so шки как раз загружались, а с 2.4.** уже нет, да и

Dynamically linked binaries, in contrast, are not com- plete when they are loaded from disk. It is therefore not possible for the kernel to immediately transfer con- trol to the application. Instead some other helper pro- gram, which obviously has to be complete, is loaded as well. This helper program is the dynamic linker. The task of the dynamic linker is it, to complete the dynamically linked application by loading the DSOs it needs (the de- pendencies) and to perform the relocations. Then finally control can be transferred to the program.

Т.е. загрузка so если нужно и настройка ссылок.

AKonia ★★
()
Последнее исправление: AKonia (всего исправлений: 1)
Ответ на: комментарий от AKonia

Т.е. загрузка so если нужно и настройка ссылок.

Это происходит независимо в рамках каждого процесса.

X512 ★★★★★
()
Ответ на: комментарий от X512

Нет, so подгружает процесс если этот so не был подгружен ранее иначе он выполняет только настройку ссылок, более того одна из ключевых плюшек so как раз и состоит в экономии памяти и отсутствии необходимости заново подгружать so, не считая возможности непересобирать исполнимые файлы при обновлении so

AKonia ★★
()
Ответ на: комментарий от AKonia

Ты говоришь ерундой.

Экономия памяти не имеет отношения к наблюдаемому из прикладного кода поведению.

Поведение у so понятное — в каждый процесс грузится своя копия so.

Экономия памяти — деталь реализации. Если запускаться на системе без поддержки MMU, экономии памяти не будет. А поведение не изменится.

wandrien ★★
()
Ответ на: комментарий от AKonia

иначе он выполняет только настройку ссылок

Это называется разделяемая память и в данном случае обслуживается ядром, загрузчик всегда вызывает один и тот же mmap() хоть первый раз, хоть 100500-ый. Это никак не влияет на логику программы и является чистой оптимизацией.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от wandrien

На уровне целеполагания нет, т.к.

Without dynamic linking, all programs would need their own copy of the these libraries and would need far more disk space and virtual memory. In dynamic linking, information is included in the ELF image’s tables for every library routine referenced. The information indicates to the dynamic linker how to locate the library routine and link it into the program’s address space.

А детали реализации - это детали реализации, ссылатся на которые нельзя, т.к. могут везде быть разными, т.к. везде разные и не поверите, но и на сисетмах без отображения в память разделяемые библиотеки не копируются к вап процессов, а отсылать к деталям реализации некорректно, т.к. описанный вами сценарий работает в случае MMU.

Что пишет Левин:

Linux adds a single uselib () system call that takes the file name and address of a library and maps it into the program address space. The startup routine bound into the executable runs down the list of libraries, doing a uselib() on each. The BSD/OS scheme uses the standard mmap () system call that maps pages of a file into the address space and a bootstrap routine that is linked into each shared library as the first thing in the library.

Т.е. отображение в вап без копирования, т.е. опять же физического копирования не происходит идёт лишь подстройка для ВАП и в целом физического копирования и не будет, а mmap не оптимизация копирования, а вариант реализации адресного отображения.

AKonia ★★
()
Последнее исправление: AKonia (всего исправлений: 2)
Ответ на: комментарий от AKonia

у каждого процесса своё адресное пространство, если ты с этим споришь, то ты пишешь херню

anonymous
()
Ответ на: комментарий от anonymous

Как раз да, у каждого процесса свой ВАП, но библиотеки в него только отображаются и физическое адресное пространство может пересекаться

AKonia ★★
()
Ответ на: комментарий от AKonia

Linux adds a single uselib () system call that takes the file name and address of a library and maps it into the program address space.

uselib объявлен устаревшим и не всегда поддерживается:

This obsolete system call is not supported by glibc. No declaration is provided in glibc headers, but, through a quirk of history, glibc versions before 2.23 did export an ABI for this system call.

Since Linux 3.15, this system call is available only when the kernel is configured with the CONFIG_USELIB option.

(c) https://man7.org/linux/man-pages/man2/uselib.2.html

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)

В плоском.

anonymous
()
Ответ на: комментарий от AKonia

Мозги не пудрите ТСу. Она спросила, как ведут себя so с позиции прикладного программиста, которому эти so использовать.

Вы пришли скор набить или на вопрос ответить?

wandrien ★★
()
Ответ на: комментарий от wandrien

своя копия so

Нам объясняли по другому. В памяти системы существует лишь одна копия libstdc++, а каждый процесс имеет свои изменяемые данные. А иначе зачем это все затевать, если можно собирать статически? Я вот только не поняла, как прцесс вызывает из этой памяти функции?

Zpp
() автор топика
Ответ на: комментарий от Zpp

Нам объясняли по другому. В памяти системы существует лишь одна копия libstdc++, а каждый процесс имеет свои изменяемые данные. А иначе зачем это все затевать, если можно собирать статически? Я вот только не поняла, как прцесс вызывает из этой памяти функции?

Сильно упрощенно, картина следующая:

В памяти системы существует такой объект как «отображение файла в память». Это означает, что система в регион адресов кладёт данные из файла, а если ей не хватает оперативной памяти, может просто выкинуть их. (А когда потребуются, снова загрузить из файла.)

Эти данные, сколько раз файл не отображай, он оперативной памяти съест одинаково. Т.к. отображается в процессы из одних и тех же физических страниц.

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

Для этого загрузчик объектов so должен модифицировать память.

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

Таким образом, с точки зрения системы, есть, например, 95% страниц, которые полностью повторяют содержимое файла (и могут быть выброшены и загружены заново при необходимости) и еще 5% страниц, которые она просто так выбросить не может, т.к. они содержат изменения, необходимые для работы so.

А с точки зрения прикладного кода, он просто загрузил содержимое so-файла в свою память, и его загруженная копия не имеет отношения к другим копиям.

Всё зависит от того, на каком уровне абстракции рассматривать этот механизм.

wandrien ★★
()
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от Zpp

Я сейчас работаю над подобным проектом. Вы сделаете мне донат?

Владимир

anonymous
()
Ответ на: комментарий от Zpp

Нам объясняли по другому. В памяти системы существует лишь одна копия libstdc++, а каждый процесс имеет свои изменяемые данные.

Плохо вам объясняли. Общие только данные для чтения такие как машинный код (секция .text) и строки/константы (секция .rodata). Глобальные переменные модуля (секция .bss) в каждом процессе свои. В каждый процесс модуль отображается по своему адресу, который обычно отличается в разных процессах.

А иначе зачем это все затевать, если можно собирать статически?

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

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

По адресу.

X512 ★★★★★
()
Ответ на: комментарий от Zpp

Почитай Керриска «Linux API. Исчерпывающее руководство» главу 41 и если будет желание то и 42-ую, там всё доходчиво описано.

AKonia ★★
()
Последнее исправление: AKonia (всего исправлений: 1)

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

slapin ★★★★★
()
Ответ на: комментарий от AKonia

читайте хотя бы у Дреппера статью о том как нужно so’шки писать или у Керриска тоже было немного по дин библиотекам.

Ссылок можно?

hobbit ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.