[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]

Программирование: Разработка и отладка программ


Общие библиотеки и частичная загрузка

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

dump -H Команда просмотра списка зависимых модулей.
-blazy В AIX версий 4.2.1 и выше - опция компоновщика, указывающая, что при компоновке модуля следует загрузить только часть зависимых модулей, если функция из этого модуля вызывается в первый раз.

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

При первом вызове функции, определенной в частично загруженном модуле, система пытается загрузить модуль с определениями и найти в нем нужную функцию. Если этот модуль не найден или если он не экспортирует данную функцию, по умолчанию выдается стандартное сообщение об ошибке, и программа завершает работу с кодом возврата 1. В приложении можно реализовать собственный обработчик ошибок путем вызова функции _lazySetErrorHandler с адресом пользовательского обработчика ошибок в качестве параметра. При вызове обработчика ошибок в него передаются три аргумента: имя модуля, имя символа и значение, обозначающее причину ошибки. Если обработчик ошибок возвращает значение, он должен возвращать адрес функции, употребляемой вместо данной. Функция _lazySetErrorHandler возвращает либо адрес обработчика ошибок, либо NULL, если обработчика нет.

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

Во-вторых, могут возникнуть ошибки в работе программ, в которых выполняется сравнение указателей на функции, поскольку у одной и той же функции может быть несколько адресов. Например, если модуль A вызывает функцию `f' из модуля B, а при компоновке модуля А указана частичная загрузка модуля B, то адрес функции `f', вычисленный в модуле A, будет отличаться от адреса функции `f', вычисленного в других модулях. Следовательно, при применении частичной загрузки два указателя на одну и ту же функцию могут быть различными.

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

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

Частичную загрузку можно применять как в приложениях с нитями, так и в приложениях без нитей.

Трассировка частичной загрузки

Специальная процедура времени выполнения позволяет обнаружить загрузку модулей на этапе выполнения. Эта процедура изменяет значение переменной среды LDLAZYDEBUG. Последнее представляет собой десятичное, восьмеричное (с префиксом 0) или шестнадцатеричное (с префиксом 0x) число, равное сумме нескольких из перечисленных ниже значений или одному из них:

1 Наличие ошибок загрузки или поиска.

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

2 Запись сообщений трассировки в поток stderr вместо stdout.

По умолчанию эти сообщения помещаются в стандартный поток вывода. Это значение позволяет помещать их в стандартный поток сообщений об ошибках.

4 Вывод имени загружаемого модуля.

Если для вызова функции необходимо загрузить новый модуль, то после обнаружения и загрузки этого модуля на экране появляется его имя. Это происходит только при обработке первой ссылки на функцию из этого модуля, т.е. после загрузки модуля он остается доступным для последующих ссылок на функции из него. Дополнительные операции загрузки не нужны.

8 Вывод имени вызываемой функции.

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

Связанная информация

Команда dump.


[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]