Почему при загрузке ТАК файл это добавляет версию в конец?

Perl system("cmd") функционируйте обычно разветвляет процесс, и в дочернем процессе, выполняет оболочку системы (обычно /bin/sh) с как аргументы, ["sh", "-c", "cmd"], иметь sh проанализируйте и выполните ту командную строку оболочки.

Как оптимизация, это может иногда обходиться без вызова оболочки, если cmd не содержит метасимволов оболочки (как заключение в кавычки символов или globbing символов или вещей как ;, &&...) кроме пространства и вкладки, но здесь у нас есть метасимволы оболочки, так как у нас есть a *.

Так, это ls -U -1 dir/* будет интерпретироваться оболочкой системы.

Это - оболочка, которая расширяется dir/* к списку соответствия файлам, переданным ls, таким образом, способ, которым это сделано, зависит от оболочки.

В терминале Вы обычно выполняете свою оболочку входа в систему, которая обычно является нет /bin/sh. Также (как отмечено peterph), та оболочка, так как это выполняется в интерактивном режиме, будет обычно читать конфигурационные файлы как ~/.zshrc (если оболочка zsh) где некоторые настройки могли бы влиять, как globbing сделан.

Например:

Моя оболочка zsh, и у меня есть a setopt dotglob в моем ~/.zshrc, так:

$ echo *
.a d é f

Не читая ~/.zshrc:

$ zsh -c 'echo *'
d é f
$ LC_ALL=C zsh -c 'echo *'
d f é

Вы заметите это zsh соблюдает локаль при сортировке списка.

$ sh -c 'echo *'
d f é

sh (который в моем случае является Debian ash) не соблюдает локаль и виды как будто в локали C.

Если Вы хотите perl system() для интерпретации командной строки с конкретной оболочкой можно записать это:

system("zsh", "-c", "cmd");

При передаче больше что один аргумент, perl system() никогда неявно называет оболочку, таким образом, выше, она разветвляет процесс, в котором она работает /bin/zsh с ["zsh", "-c", "cmd"] как аргументы.

3
22.04.2015, 23:14
1 ответ

Когда компоновщик создает исполняемый файл (или другую общую библиотеку), он ищет запрашиваемые библиотеки, используя -l, префикс lib и суффикс .so к имени. Например, если вы запрашиваете -lcrypto, то он ищет libcrypto.so.

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

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

Сначала опишу, что было бы при отсутствии этой конвенции:

Заголовки разработки (.h файлы) соединяются с конкретной версией библиотеки, и . Так что файл содержит и эту версию:

/usr/include/mylibrary.h
/usr/lib/libmylibrary.so

Против этой версии библиотеки скомпилировано приложение myapp, которое во время выполнения загружает /usr/lib/libmylibrary.so.

Позже библиотека обновляется до новой версии. И файл .h, и файл .so заменяются на новую версию. К сожалению, новая версия имеет несовместимый ABI.

Теперь, когда выполняется myapp, он ломается или проявляет неопределенное поведение, так как был скомпилирован с одной версией с одним ABI, но загрузил другую версию во время выполнения.

Что происходит с соглашением о сонаме:

Библиотека установлена следующим образом:

/usr/include/mylibrary.h
/usr/lib/libmylibrary.so -> libmylibrary.so.1
/usr/lib/libmylibrary.so.1

И /usr/lib/libmylibrary.so.1 встроил в нее сонамеренное имя libmylibrary.so.1.

Когда myapp построен, он находит /usr/lib/libmylibrary.so.so, но компоновщик следует за симлинком и фактически загружает /usr/lib/libmylibrary.so.1. Более того, сонамер libmylibrary.so.1 - это то, что на самом деле записывается внутри myapp. Во время выполнения myapp загружает /usr/lib/libmylibrary.so.1 напрямую, минуя симлинк.

Позже библиотека обновляется до новой версии с несовместимым ABI. Оба файла .h и .so заменяются на новую версию. Появляется новый файл libmylibrary.so.2. Файл libmylibrary.so.1 из старой версии остался один.

/usr/include/mylibrary.h
/usr/lib/libmylibrary.so -> libmylibrary.so.2
/usr/lib/libmylibrary.so.1
/usr/lib/libmylibrary.so.2

Теперь, когда myapp выполнен, продолжает загружать libmylibrary.so.1 и продолжает функционировать, как и ожидалось. Но если установлены другие новые приложения или перекомпилирована сама myapp, то последует symlink и будет использована новая версия.


Проблема в том, что когда ваше приложение было скомпоновано, компоновщик нашел библиотеку с именем сонастройки libcrypto.so.1.0.0.

Была ли ваша копия libcrypto.so сгенерирована с сонамеренным именем, если libcrypto.so.1. .0.0?

Другая возможность, вполне вероятно, что ваша копия libcrypto.so не имеет сонамера, но компоновщик на самом деле нашел и использовал system версию libcrypto.so (из OpenSSL), и вот откуда он получил сонамеренное имя.

1
27.01.2020, 21:31

Теги

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