dlopen работает второй раз на плохой общей библиотеке на Ubuntu 11.04; правильно делает на Centos 5.5 - PullRequest
0 голосов
/ 06 июля 2011

У меня плохая общая библиотека (неопределенный символ).

Когда я в первый раз вызываю dlopen (), я получаю NULL-результат с правильным сообщением об ошибке от dlerror ().

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

Эта проблема возникает в Ubuntu 11.04 (IIRC, 10.10 не имела этой проблемы).В Centos 5.5 этой проблемы нет.

В частности, эта проблема возникает в интерпретаторе Tcl.Он попытается загрузить разделяемую библиотеку, сначала с канонизированным абсолютным путем, а если это снова не удастся, буквально с точной строкой пути, указанной пользователем.В моем случае оба должны потерпеть неудачу, но второй вызов неправильно выполняется в Ubuntu 11.04.

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

Такой программы достаточно, чтобы показать проблему с моей производственной библиотекой:

#include <stdio.h>
#include <dlfcn.h>

int main()
{
  void* h;

  h = dlopen("./prod.so", RTLD_NOW | RTLD_LOCAL);
  printf("h is %p\n", h);
  printf("err is %s\n", dlerror());
  h = dlopen("./prod.so", RTLD_NOW | RTLD_LOCAL);
  printf("h is %p\n", h);
}

1 Ответ

1 голос
/ 06 июля 2011

Время от времени я иногда сталкиваюсь с этой проблемой, но пока не могу точно определить, что ее вызвало (мне еще предстоит найти нужную вещь для Google, но это не то, что в Ubuntu кажется, что изменение заголовка, так что трудно найти). Кто-то упомянул мне, передавая IRC, что было не так, но это было некоторое время назад, у меня была проблема с глазными яблоками в другой момент, и я не сохранил достаточно информации (записанной или в памяти), чтобы иметь возможность реконструировать это. Так что это мое лучшее воспоминание ...

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

Короче, это чья-то ошибка, но чей я не знаю. Многие (но не все!) Дистрибьюторы Linux не очень хорошо реагируют на проблемы, которые они обнаруживают или создают.

Примечание: если ваш код выше является прокси для команды Tcl load, помните, что это сложная область сама по себе .

...