Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Перезагрузка обновленной библиотеки


Автор: admsasha 6.12.2017, 03:48
Требуется сделать без перезапуска программы обновление плагинов, которые реализованы через библиотеки.

Тестовый код простой
Код

    void* handle = dlopen("libs/test.so", RTLD_LAZY);
    sleep(5);
    dlclose(handle);


Проблема в том, что если во время sleep переписать libs/test.so, то программа на dlclose(handle) упадет. Как корректно завершить или отловить это событие ? Как почистить память от этой библиотеки, даже если она физические была заменена ?

Автор: xvr 6.12.2017, 13:51
Цитата(admsasha @  6.12.2017,  03:48 Найти цитируемый пост)
Проблема в том, что если во время sleep переписать libs/test.so, то программа на dlclose(handle) упадет. 

Если test.so именно переписать, то всё упадет не доходя до dlclose. Удалите сначала сам файл с test.so, а потом создавайте заново - должно работать.
Если хотите, что бы ваша программа не зависила от перезаписи в полёте, то копируйте test.so во внутреннюю директорию (предварительно стерев оттуда предыдущую версию) и делайте dlopen оттуда

Автор: admsasha 7.12.2017, 03:43
Цитата(xvr @  6.12.2017,  20:51 Найти цитируемый пост)
Если test.so именно переписать, то всё упадет не доходя до dlclose. Удалите сначала сам файл с test.so, а потом создавайте заново - должно работать.
 Нет, это не помогат. Как видно из кода, следующая операция после sleep закрытие библиотеки. 

Цитата(xvr @  6.12.2017,  20:51 Найти цитируемый пост)
Если хотите, что бы ваша программа не зависила от перезаписи в полёте, то копируйте test.so во внутреннюю директорию (предварительно стерев оттуда предыдущую версию) и делайте dlopen оттуда
 Вот я так же подумывал. И скорее всего и придется так делать. Не очень красивое решение.

Автор: xvr 7.12.2017, 18:30
Цитата(admsasha @  7.12.2017,  03:43 Найти цитируемый пост)
 Нет, это не помогат. Как видно из кода, следующая операция после sleep закрытие библиотеки. 

Это не важно. Важно то, что библиотека при dlopen мапируется в память, и если вы ее в это время начинаете менять на файловой системе (например переписывать), то может измениться и образ в памяти (это зависит от того, как динамический загрузчик мапировал библиотеку в память). А dlclose потом полезет читать рантайм динамические данные, что бы удалить инфу о загруженной библиотеке из памяти. Если образ был изменен, то тот мусор, который прочтет линкер, может сломать всё.

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

Автор: admsasha 9.12.2017, 13:20
Похоже на баг

https://sourceware.org/bugzilla/show_bug.cgi?id=19773

Автор: xvr 11.12.2017, 14:33
Не баг, а фича. Там же написано, что так и должно быть.

 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)