Изучаем Linux, 101: Управление общими библиотеками

Определение и загрузка библиотек, необходимых для работы программ

Из этой статьи вы узнаете, какие общие библиотеки нужны для выполнения программ Linux®, и как загружать эти библиотеки. Вы можете использовать этот материал для подготовки к экзамену LPI 101 программы сертификации на администратора Linux начального уровня или просто для общего развития.

Об этой серии

Эта серия статей поможет вам освоить задачи администрирования операционной системы Linux. Вы также можете использовать материал этих статей для подготовки к экзаменам первого уровня сертификации профессионального института Linux (LPIC-1).

Чтобы посмотреть описания статей этой серии и получить ссылки на них, обратитесь к нашему перечню материалов для подготовки к экзаменам LPIC-1. Этот перечень постоянно дополняется новыми статьями по мере их готовности и содержит самые последние (по состоянию на апрель 2009 года) цели экзаменов сертификации LPIC-1. Если какая-либо статья отсутствует в перечне, можно найти ее более раннюю версию, соответствующую предыдущим целям LPIC-1 (до апреля 2009 года), обратившись к нашим руководствам для подготовки к экзаменам института Linux Professional Institute.

Краткий обзор

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

  • Определять, какие библиотеки необходимы той или иной программе.
  • Узнаете, как операционная система находит общие библиотеки.
  • Загружать общие библиотеки.

Эта статья поможет вам подготовиться к сдаче экзамена LPI 101 на администратора начального уровня (LPIC-1) и содержит материалы цели 102.3 темы 102. Цель имеет вес 1.

Необходимые условия

Чтобы извлечь наибольшую пользу из наших статей, необходимо обладать базовыми знаниями о Linux и иметь компьютер с Linux, на котором можно будет выполнять все встречающиеся команды. Иногда различные версии программ выводят результаты по-разному, поэтому содержимое листингов статей может слегка отличаться от результатов, полученных на вашем компьютере. В частности, многие примеры этой статьи выполнялись в 64-разрядных операционных системах. Чтобы продемонстрировать существенные отличия, мы включили некоторые примеры, выполненные в 32-разрядных ОС.


Статическая и динамическая компоновка

Как связаться с Яном

Ян – один из наших наиболее популярных и плодовитых авторов. Ознакомьтесь со всеми статьями Яна (EN), опубликованными на сайте developerWorks. Вы можете найти контактные данные в профиле Яна и связаться с ним, а также с другими авторами и участниками ресурса My developerWorks.

В Linux существует два типа исполняемых программ:

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

Интересным примером во многих Linux-системах является команда ln (/bin/ln), предназначенная для создания связей между файлами в виде жестких или мягких (символических) ссылок и использующая общие библиотеки. Общие библиотеки часто используют символические ссылки между именем библиотеки ее и отдельными версиями, поэтому если по какой-то причине эти ссылки будут удалены или повреждены, команда ln может перестать работать, приводя к ошибке зацикливания. Для предотвращения таких ситуаций в некоторых Linux-системах имеется статически скомпонованная версия программы lnsln (/sbin/sln). В листинге 1 показана большая разница в размерах динамически скомпонованной программы ln и статически скомпонованной sln. Этот пример был выполнен в 64-разрядной операционной системе Fedora 12.

Листинг 1. Размеры sln и ln
[ian@echidna ~]$ ls -l /sbin/sln /bin/ln
-rwxr-xr-x. 1 root root  47384 2010-01-12 09:35 /bin/ln
-rwxr-xr-x. 1 root root 603680 2010-01-04 09:07 /sbin/sln

Какие библиотеки необходимы?

Хотя это выходит за рамки текущих требований экзамена LPI по данной теме, вам все же следует знать, что сегодня многие операционные системы Linux работают на компьютерах с поддержкой как 32-, так и 64-разрядных операций. В связи с этим многие библиотеки скомпилированы в версиях для 32- и 64-разрядных систем. 64-разрядные версии обычно хранятся в директории /lib64, а 32-разрядные версии – в традиционной директории /lib. В стандартной 64-разрядной Linux-системе вы, вероятно, обнаружите две версии библиотеки libc: /lib/libc-2.11.1.so и /lib64/libc-2.11.1.so. Эти две библиотеки обеспечивают выполнение 32- и 64-разрядных программ, написанных на C, в 64-разрядной системе Linux.

Команда ldd

Как можно убедиться в том, что программа была скомпонована статически, если не принимать во внимание ее возможно больший размер? А если программа была скомпонована динамически, как узнать, какие библиотеки требуются для ее работы? На оба этих вопроса поможет ответить команда ldd. Если вы работаете с таким дистрибутивом Linux, как Debian или Ubuntu, то, вероятно, в ней отсутствует исполняемый файл sln; вы можете также проверить наличие файла /sbin/ldconfig. В листинге 2 показан вывод команды ldd для исполняемых файлов ln, sln и ldconfig. Пример был выполнен в 64-разрядной операционной системе Fedora 12 (echidna). Также для сравнения приведен пример этой команды для файла /bin/ln, выполненный в 32-разрядной ОС Fedora 8 (pinguino).

Листинг 2. Вывод команды ldd для sln и ln
[ian@echidna ~]$ #Fedora 12 64-bit
[ian@echidna ~]$ ldd /sbin/sln /sbin/ldconfig /bin/ln
/sbin/sln:
        not a dynamic executable
/sbin/ldconfig:
        not a dynamic executable
/bin/ln:
        linux-vdso.so.1 =>  (0x00007fff644af000)
        libc.so.6 => /lib64/libc.so.6 (0x00000037eb800000)
        /lib64/ld-linux-x86-64.so.2 (0x00000037eb400000)

[ian@pinguino ~]$ # Fedora 8 32-bit
[ian@pinguino ~]$ ldd /bin/ln
        linux-gate.so.1 =>  (0x00110000)
        libc.so.6 => /lib/libc.so.6 (0x00a57000)
        /lib/ld-linux.so.2 (0x00a38000)

Поскольку в действительности программа ldd проверяет факт динамической компоновки, выводимое ей сообщение "not a dynamic executable" говорит нам о том, что обе программы – sln и ldconfig – были скомпонованы статически; также программа сообщает о том, что команде ln требуются три общих библиотеки (linux-vdso.so.1, libc.so.6 и /lib64/ld-linux-x86-64.so.2). Заметьте, что расширение .so означает shared objects (совместно используемый объект), т. е. библиотека является динамической. В листинге мы видим три различных блока с информацией:

linux-vdso.so.1
представляет собой виртуальный динамический разделяемый объект (Virtual Dynamic Shared Object, VDSO), который мы рассмотрим чуть позже. В ОС Fedora 8 в списке также присутствует библиотека linux-gate.so.1.
libc.so.6
имеет указатель на /lib64/libc.so.6.
/lib64/ld-linux-x86-64.so.2
представляет собой абсолютный путь к другой библиотеке.

Выполнив в листинге 3 команду ls -l, мы видим, что две последние библиотеки, в свою очередь, являются символическими ссылками на определенные версии библиотек. Этот пример был выполнен в 64-разрядной операционной системе Fedora 12.

Листинг 3. Символические ссылки на библиотеки
[ian@echidna ~]$ ls -l /lib64/libc.so.6 /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx. 1 root root 12 2010-01-14 14:24 /lib64/ld-linux-x86-64.so.2 -> ld-2.11.1.so
lrwxrwxrwx. 1 root root 14 2010-01-14 14:24 /lib64/libc.so.6 -> libc-2.11.1.so

Виртуальные динамические разделяемые объекты Linux

В те времена, когда процессоры с архитектурой x86 только появились, взаимодействие пользовательских приложений со службами операционной системы осуществлялось с помощью прерываний. По мере создания более мощных процессоров эта схема взаимодействия становилась узким местом системы. Во всех процессорах, начиная с Pentium® II, Intel® реализовала механизм быстрых системных вызовов (Fast System Call), в котором вместо прерываний используются инструкции SYSENTER и SYSEXIT, ускоряющие выполнение системных вызовов.

Библиотека linux-vdso.so.1 является виртуальной библиотекой, или виртуальным динамически разделяемым объектом (VDSO), который размещается только в адресном пространстве отдельной программы. В более ранних системах эта библиотека называлась linux-gate.so.1. Эта виртуальная библиотека содержит всю необходимую логику, обеспечивающую для пользовательских приложений наиболее быстрый доступ к системным функциям в зависимости от архитектуры процессора – либо через прерывания, либо (для большинства современных процессоров) через механизм быстрых системных вызовов.


Динамическая загрузка

С учетом всего сказанного выше может показаться необычным, что библиотеки /lib/ld-linux.so.2 и ее 64-разрядная версия, /lib64/ld-linux-x86-64.so.2, которые выглядят как общие библиотеки, на самом деле являются самыми настоящими исполняемыми файлами. Эти библиотеки содержат код, отвечающий за динамическую загрузку. Этот код считывает информацию из заголовка исполняемого файла, созданного в формате исполняемых и компонуемых модулей (Executable and Linking Format, ELF), и на ее основании определяет, какие библиотеки требуются данному приложению и должны быть загружены. После этого выполняется динамическая компоновка приложения, приводящая в соответствие указатели его адресов и указатели адресов загруженных библиотек, в результате чего приложение может быть запущено.

Man-страница библиотеки ld-linux.so также содержит описание библиотеки ld.so, которая выполняет эти же функции для приложений, созданных в старом двоичном формате a.out. В листинге 4 продемонстрировано использование опции --list для семейства библиотек ld-linux.so: для команды ln выводится та же самая информация, что и для команды ldd в листинге 2.

Листинг 4. Использование ld-linux.so для получения списка требуемых библиотек
[ian@echidna ~]$ /lib64/ld-linux-x86-64.so.2 --list /bin/ln
        linux-vdso.so.1 =>  (0x00007fffc9fff000)
        libc.so.6 => /lib64/libc.so.6 (0x00000037eb800000)
        /lib64/ld-linux-x86-64.so.2 (0x00000037eb400000)

[ian@pinguino ~]$ /lib/ld-linux.so.2 --list /bin/ln
        linux-gate.so.1 =>  (0x00110000)
        libc.so.6 => /lib/libc.so.6 (0x00a57000)
        /lib/ld-linux.so.2 (0x00a38000)

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


Настройка динамических библиотек

Итак, как же динамический загрузчик узнает, где искать исполняемые файлы? Как и везде в Linux, для этого используется конфигурационный файл, расположенный в директории /etc. Фактически, это два конфигурационных файла /etc/ld/so/conf и /etc/ld.so.cache. В листинге 5 показано содержимое файла /etc/ld.so.conf в 64-разрядной операционной системе Fedora 12. Обратите внимание на то, что в /etc/ld.so.conf указано, что необходимо включить в конфигурацию все файлы .conf из поддиректории ld.so.conf.d. В более старых системах директива include для директории /etc/ld.so.conf.d может не использоваться, а все необходимые файлы могут быть перечислены непосредственно в файле /etc/ld/so/conf. В вашей операционной системе содержимое файла /etc/ld.so.conf или директории /etc/ld.so.conf.d может отличаться.

Листинг 5. Содержимое файла /etc/ld.so.conf
[ian@echidna ~]$ cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
[ian@echidna ~]$ ls /etc/ld.so.conf.d/*.conf
/etc/ld.so.conf.d/kernel-2.6.31.12-174.2.19.fc12.x86_64.conf
/etc/ld.so.conf.d/kernel-2.6.31.12-174.2.22.fc12.x86_64.conf
/etc/ld.so.conf.d/kernel-2.6.31.12-174.2.3.fc12.x86_64.conf
/etc/ld.so.conf.d/mysql-x86_64.conf
/etc/ld.so.conf.d/qt-x86_64.conf
/etc/ld.so.conf.d/tix-x86_64.conf
/etc/ld.so.conf.d/xulrunner-64.conf

Загрузка программ должна происходить быстро, поэтому используйте команду ldconfig для обработки файла ld.so.conf, всех файлов из директории ld.so.conf.d, библиотек из доверенных директорий /lib и /usr/lib, а также других библиотек, указанных в командной строке. Команда ldconfig создает в файле /etc/ld.so.cache все необходимые связи, а также кэш для наиболее часто используемых библиотек. Динамический загрузчик использует информацию из кэша ld.so.cache для поиска файлов, которые необходимо динамически загрузить и скомпоновать. Если вы вносите изменения в файл ld.so.conf (или добавляете новые файлы в директорию ld.so.conf.d), вы должны запустить команду ldconfig (от имени пользователя root) для перестроения (rebuild) файла ld.so.cache.

Обычно для перестроения файла ld.so.cache команда ldconfig запускается без параметров. Тем не менее, существует несколько параметров, с помощью которых можно изменить поведение этой программы. Как обычно, дополнительная информация доступна по команде man ldconfig. В листинге 6 продемонстрировано использование параметра -p для отображения содержимого файла ld.so.cache.

Листинг 6. Вывод содержимого файла ld.so.cache с помощью ldconfig
[ian@lyrebird ian]$ /sbin/ldconfig -p | less
1602 libs found in cache `/etc/ld.so.cache'
        libzip.so.1 (libc6,x86-64) => /usr/lib64/libzip.so.1
        libz.so.1 (libc6,x86-64) => /lib64/libz.so.1
        libz.so (libc6,x86-64) => /usr/lib64/libz.so
        libx86.so.1 (libc6,x86-64) => /usr/lib64/libx86.so.1
        libx11globalcomm.so.1 (libc6,x86-64) => /usr/lib64/libx11globalcomm.so.1
        libxul.so (libc6,x86-64) => /usr/lib64/xulrunner-1.9.1/libxul.so
        libxtables.so.2 (libc6,x86-64) => /usr/lib64/libxtables.so.2
        libxslt.so.1 (libc6,x86-64) => /usr/lib64/libxslt.so.1
        libxslt.so (libc6,x86-64) => /usr/lib64/libxslt.so
        libxpcom.so (libc6,x86-64) => /usr/lib64/xulrunner-1.9.1/libxpcom.so
        libxml2.so.2 (libc6,x86-64) => /usr/lib64/libxml2.so.2
        libxml2.so (libc6,x86-64) => /usr/lib64/libxml2.so
       ...
        libABRTdUtils.so.0 (libc6,x86-64) => /usr/lib64/libABRTdUtils.so.0
        libABRTUtils.so.0 (libc6,x86-64) => /usr/lib64/libABRTUtils.so.0
        ld-linux.so.2 (ELF) => /lib/ld-linux.so.2
        ld-linux-x86-64.so.2 (libc6,x86-64) => /lib64/ld-linux-x86-64.so.2

Загрузка требуемых библиотек

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

Подобно тому, как вы можете изменить переменную PATH для поиска исполняемых файлов, вы можете изменить и значение переменной LD_LIBRARY_PATH, указав через двоеточие директории, в которых будет выполняться поиск общих библиотек прежде чем будут использованы системные библиотеки, перечисленные в файле ld.so.cache. Например, вы можете использовать следующую команду:

export LD_LIBRARY_PATH=/usr/lib/oldstuff:/opt/IBM/AgentController/lib

Для получения дополнительной информации, а также ссылок на другие статьи этой серии обратитесь к разделу Ресурсы.

Ресурсы

Научиться

  • Оригинал статьи: Learn Linux, 101: Manage shared libraries (EN).
  • Используйте перечень материалов для подготовки к экзаменам LPIC-1 (EN) для поиска статей developerWorks, которые помогут вам подготовиться к сдаче экзаменов программы сертификации LPIC-1, основанной на целях по состоянию на апрель 2009 года.
  • На Web-сайте программы сертификации LPIC (EN) вы найдете подробные цели, списки задач и примерные вопросы всех трех уровней сертификации на администратора Linux-систем профессионального института Linux. В частности, на этом сайте представлены цели экзаменов LPI 101 и LPI 102 по состоянию на апрель 2009 года. Всегда обращайтесь к Web-сайту программы сертификации LPIC, чтобы узнать последние цели.
  • Просмотрите всю серию статей для подготовки к экзаменам института LPI (EN) на сайте developerWorks, основанных на предыдущих целях, определенных до апреля 2009 года, чтобы изучить основы администрирования Linux и подготовиться к экзаменам для получения сертификата администратора Linux.
  • Web-сайт Linux Documentation Project (EN) содержит большое количество полезной документации, в особенности, HOWTO-руководств.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux
ArticleID=750848
ArticleTitle=Изучаем Linux, 101: Управление общими библиотеками
publish-date=08042011