Gentoo Logo

Предупреждение : Этот документ недействителен и больше не поддерживается.


Руководство по предварительному связыванию в Gentoo Linux

Содержание:

1.  Введение

Что такое предварительное связывание (Prelink) и как оно может помочь мне?

Большинство приложений используют разделяемые библиотеки. Эти разделяемые библиотеки должны быть загружены в память во время выполнения программы, при этом необходимо определить различные символьные ссылки. Для большинства небольших программ динамическое связывание происходит очень быстро. Но для программ, написанных на C++, имеющих много библиотечных зависимостей, динамическое связывание может занять много времени.

На большинстве систем, библиотеки обычно остаются неизменными и когда программа запускается, операции необходимые для связывания, каждый раз одинаковы. Предварительное связывание использует данную особенность, выполняя связывание и сохраняя библиотеки в выполняемом файле, фактически уже связанными. Для связывания, вам потребуется ld-linux.so в glibc; для распознавания предварительного связывания версия glibc должна быть >= 2.3.1-r2

Предварительное связывание может уменьшить время загрузки приложений. Например, типичные программы KDE могут загружаться на 50% быстрее. Необходимым условием является перезапуск процесса предварительного связывания каждый раз при обновлении библиотек для программ, которые на них ссылаются.

Резюме

  • Предварительное связывание производится программой, имеющей название, как ни странно, prelink. Она изменяет выполняемый файл таким образом, что он запускается быстрее.
  • Если зависимые от приложения библиотеки были изменены после того, как были предварительно связаны с приложением, то они потребуют повторного предварительного связывания, иначе вы потеряете преимущества в скорости загрузки.
  • Изменения выполняемого файла полностью обратимы, поскольку программа prelink имеет функцию undo.
  • Новые версии portage могут обрабатывать, при помощи программы prelink, изменяющиеся контрольные суммы MD5 и поля mtime выполняемых файлов.
  • У вас должен быть glibc-2.3.1-r2 или более новый, и бинарные файлы должны быть скомпилированы с binutils-2.13.90.0.xx или выше.

2.  Инициализация предварительного связывания

Установка программ

Примечание: Я подразумеваю, что у вас есть Gentoo-1.4, который был собран при помощи gcc-3.2 или более поздней версии и binutils-2.13.90.0.xx. Это требуется для того, что бы выполняемые файлы могли быть предварительно связаны.

Предупреждение: Должен быть установлен glibc 2.3.1 или более новый, иначе программа prelink может испортить все ваши выполняемые файлы!

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

Листинг 2.1: Обновление вашего дерева портежей

# emerge sync

Далее, убедитесь, что у вас установлен portage-2.0.26 или более новый. Это требуется для того, что бы portage могло распознать предварительно связанные выполняемые файлы и при необходимости корректно их удалить. Т.к. предварительное связывание изменяет контрольную сумму MD5 бинарных файлов.

Листинг 2.2: Проверка версии дерева портежей

# emerge ">=portage-2.0.46"

Теперь вы можете вызвать emerge для программы предварительного связывания. Процесс emerge автоматически проверит, что ваша система может безопасно выполнять предварительное связывание.

Листинг 2.3: Устанавливаем предварительное связывание

# emerge prelink

Некоторые люди, в ходе выполнения тестов, получают ошибки выполняя emerge для программы prelink. Тесты размещены в пакете из соображений безопасности, предварительное связывание будет непредсказуемым, если их отменить. Эти ошибки обычно связаны с базовыми пакетами, такими как binutils, gcc и glibс. В таком случае попробуйте выполнить emerge этих пакетов повторно.

Примечание: Если ошибки продолжают появляться, попробуйте скомпилировать и протестировать программу prelink самостоятельно (./configure ; make ; make check ). В случае сбоя вы можете просмотреть *.log файлы в директории с набором тестов. Они могут дать вам некоторые полезные подсказки.

Если вы имеете набор действий, которые демонстрируют ошибки в другой системе, пожалуйста отправьте его Stefan Jones.

Настройка

Portage автоматически генерирует файл /etc/prelink.conf, который говорит программе prelink какие файлы требуется предварительно связать.

К сожалению, вы не сможете предварительно связать файлы, которые были скомпилированы старыми версиями пакета binutils. Большинство таких приложений поставляется уже скомпилированными, не имея исходных кодов, и устанавливаются в каталоге /opt. Создайте следующий файл, для того, что бы запретить программе prelink использовать предварительное связывание для подобных файлов.

Листинг 2.4: /etc/env.d/99prelink

PRELINK_PATH_MASK="/opt"

Примечание: Вы можете добавить больше или меньше директорий, в список, разделённый двоеточиями.

3.  Предварительное связывание

Применение предварительного связывания

Я использую следующую команду для предварительного связывания всех бинарных файлов в директориях, заданных в файле /etc/prelink.conf.

Листинг 3.1: Предварительное связывание заданных файлов

# prelink -afmR

Предупреждение: Наблюдалось, что при наличии небольшого свободного пространства в момент выполнения предварительного связывания для всей системы, существует вероятность усечения выполняемых файлов. Результатом может стать испорченная система. Используйте команду file или readelf для проверки целостности выполняемых файлов. Также вы можете заранее проверить наличие свободного места командой df -h

Описание опций:
-a All, применить предварительное связывание ко всем выполняемым файлам.
-f Вынуждает повторить предварительное связывание для файлов, которые уже подвергались ему. Это требуется т.к. программа prelink прекращает обработку существующих старых связанных файлов, зависимые библиотеки которых могли измениться.
-m Сохраняет пространство виртуальной памяти. Это требуется, если вы имеете много библиотек, которые необходимо связать.
-R Random, -- Выбирает случайный порядок адресов, это увеличивает безопасность против переполнений буферов.

Примечание: Более подробно об опциях можно узнать, набрав man prelink

4.  Известные проблемы и методы их решения

"Предварительное связывание не работает с разделяемой библиотекой, собранной без опции PIC"

Причиной данной проблемы являются объектные файлы разделяемой библиотеки, скомпилированные без опции gcc -fPIC.

Далее следует список проблемных библиотек и список пакетов, для которых требуется повторно вызвать emerge, в случае возникновения данной проблемы.

Листинг 4.1: Исправления

(Для библиотеки ORBit /usr/lib/libIIOP.so.0.5.17)
emerge ">=sys-apps/tcp-wrappers-7.6-r4" ORBit
(Для библиотеки zlib  /usr/lib/libz.so.1.1.4)
emerge ">=sys-libs/zlib-1.1.4"
(Для svgalib, /usr/lib/libsvga.so.xx)
emerge ">=media-libs/svgalib-1.9.16"
(Для библиотеки XFree openGL, libGLU.so.1)
emerge ">=x11-base/xfree-4.2.1-r2"
(Для libpcap.so.0.6)
emerge ">=net-libs/libpcap-0.7.1-r2"
(Для библиотеки lcms, /usr/lib/liblcms.so.1)
emerge ">=media-libs/lcms-1.09"

Примечание: Многие библиотеки статично связаны с zlib и/или tcp-wrappers, так что сначала попробуйте выполнить emerge для них, после чего, повторно запустите emerge для проблемных библиотек.

Если вы имеете проблемы с предварительным связыванием QT/KDE, то сначала попытайтесь обновить x11-base/xfree до версии 4.2.1-r2 или более новой и x11-libs/qt до версии 3.1.0-r1 или более новой. Если QT так и не работает, тогда попробуйте скомпилировать его без поддержки xinerama, задав строку myconf="-no-xinerama ${myconf}" в файле ebuild для qt.

Далее приводится список библиотек, которые пока не работают или не могут работать вообще:

  • Библиотеки в пакете wine, включая windex. Они в любом случае не могут ускорить выполняемые файлы MS Windows.
  • Библиотека в media-video/mjpgtools, /usr/lib/liblavfile-1.6.so.0

Если у вас есть проблемы с библиотекой, которой нет в списке, пожалуйста сообщите об этом, предпочтительно, добавив -fPIC к соответствующим CFLAGS.

Прерывание предварительного связывания файла, с выводом сообщения, вида: "1631 Aborted ...."

Вам необходимо использовать опцию -f программы prelink; т.е. повторить предварительное связывание для всей системы с нуля. Попробуйте запустить prelink -af

"Ошибка: <file>: error while loading shared libraries: unexpected reloc type..."

Это было исправлено в пакете sys-libs/glibc-2.3.1-r2 2002/11/18, выполните emerge для glibc, если у вас более старая версия.

Так же запустите prelink -u -a -m ; prelink -a -m это должно помочь. Если все это не помогает, просто запустите prelink -u <file>

У меня проблемы с библиотеками Nvidia openGL

Ускоренные библиотеки openGL идущие с пакетом nvidia-glx скомпилированы нестандартным образом, и программа prelink выводит массу предупреждений. Здесь нет повода для беспокойства, и это не может быть исправленo кем-либо помимо компании nvidia. Вы всегда можете вернуться к xfree версии библиотеки libGL.so, если вам не требуется ускорение 3D. Хотя драйвер xfree nvidia работает нормально.

После предварительного связывания моей системы, некоторые статичные выполняемые файлы более не работают

Там где участвует glibc, не бывает такой вещи как 100% статичный выполняемый файл. Если вы статично скомпилировали выполняемый файл с glibс, он может продолжать оставаться зависимым от других системных файлов. Далее приводится объяснение от Dick Howell.

"Я предполагал, что все должно находиться в скачанном файле и не должно быть никаких зависимостей с локальными библиотеками на целевой системе. К сожалению, в Linux, и я думаю везде, где используется GLIBC, это до сих пор не совсем верно. Существует библиотека "libnss" (name service switch - переключатель сервиса имён, некоторые люди думают, что это network secutiry system - сетевая система безопасности) которая предоставляет функции для доступа к различным базам данных для аутентификации, сетевой информации и для других вещей. Эта библиотека предполагает сделать приложения независимыми от отдельно сконфигурированных сетевых окружений машины. Хорошая идея, но изменения GLIBC может вести к проблемам её загрузки. И вы не можете статически связать "libnss" так как она сконфигурирована для каждой машины индивидуально. Я думаю, что, главным образом, это происходит из-за статического связывания других GLIBC библиотек, особенно "libpthread, "libm" и "libc", откуда приходят несовместимые вызовы к функциям "libnss""

Предварительное связывание обрывается с ошибкой"prelink: dso.c:306: fdopen_dso: Assertion `j == k' failed."

Это известная проблема любезно продиагностированная здесь. Программа prelink не может справиться с выполняемыми файлами сжатыми методом UPX. Для версии prelink-20021213 нет другого способа решить эту проблему, кроме как спрятать выполняемые файлы во время предварительного связывания. Смотрите раздел конфигурации выше, где обсуждается вопрос о том, как это осуществить.

5.  Заключение

Предварительное связывание может решительно ускорить время запуска для некоторых больших приложений. Его поддержка встроена в дерево портежей. Предварительное связывание безопасно, т.к. вы всегда можете отменить его действие для любого выполняемого файла, если вы столкнётесь с какими-либо проблемами. Помните что когда вы обновляете glibc или другие библиотеки, с которыми вы осуществили предварительное связывание, вам надо будет перезапустить prelink. В общем, удачи!



Для печати

Обновлено 12 мая 2003

Исходный документ для этого перевода больше не поддерживается

Аннотация: Данное руководство информирует о том, как использовать поддержку предварительного связывания в дереве портежей версии 2.0.46 или более поздней.

Stefan Jones
автор

John P. Davis
редактор

Jorge Paulo
редактор

Денис Залетов
переводчик

Юлия Залетова
редактор перевода

Сергей Кулешов
редактор перевода

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.