Russian Qt Forum
Апрель 20, 2024, 12:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: (РЕШЕНО) Ошибки при загрузке плагинов  (Прочитано 9418 раз)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« : Июнь 30, 2015, 20:07 »

Собрал всё приложение в Release, посмотреть как работает снаружи QtCreator. При запуске внутри QtCreator как для отладки, так и просто запуске, оба варианта Debug и Release работают нормально. У приложения около 90 плагинов. При запуске в QtCreator всё грузится, всё работает как ожидается во всех вариантах.

Запускаю Release снаружи QtCreator - и получаю сообщения, что два плагина не загрузились. Ошибка системная, 0-й указатель возвращает метод QPluginLoader::instance(), то есть до моего кода плагинов еще даже дело не дошло.

Код:
QDir dir; // каталог плагинов 
QString name; // имя очередного плагина с расширением
......
    QPluginLoader* PluginLoader = new QPluginLoader( dir.absoluteFilePath( name ) );
    if( PluginLoader == 0 )
    {....не важно return;}
    QObject* plugin = PluginLoader->instance();
    if( plugin )
    {
........ инициализация и пр.
    }
    else
        QMessageBox::critical(0,tr("ОШИБКА ПРИ ЗАГРУЗКЕ!"), dir.absoluteFilePath( name ) );
Эту ошибку и получаю с полными маршрутами двух плагинов. Они не первые и не последние в каталоге, грузятся среди всех остальных. Внутренне от остальных отличаются только их спецификой, схема построения у всех плагинов абсолютно одинаковая. Вообще механизм используется с 2011 года и никаких проблем раньше не было. Пару месяцев назад тоже запускал Release - не было проблемы, но и этих двух плагинов тоже еще не было. При каждом запуске ошибка только у этих двух плагинов, не плавающая. Если убрать эти два плагина, то ошибки нет, все остальные грузятся.

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

Запустил вне QtCreator вариант Debug - бум, эти же два плагина не грузятся.  В замешательстве

Даже не понятно, куда смотреть, и что проверять, механзим загрузки давно выглядел отлаженным. Чем отличается запуск внутри QtCreator (НЕ ОТЛАДКА!, запуск по Ctrl-R) от запуска вне? Ну кроме установки маршрута "Рабочий каталог". Маршруты проверял - всё на месте, все маршруты есть, да они и совершенно пофиг обоим плагинам. Делал текущим тот же каталог, что и в настройках QtCreator - по барабану.

Что вообще может быть причиной такого отказа? PluginLoader создан, но сам код плагина не загрузился, или мой объект не создался.

ЗЫ: увидел, что есть QPluginLoader::errorString(), а там бред какой-то - "The specified module cannot be found", но оба файла на месте, и все остальные из этого же каталога грузятся! может, конечно, ошибки на файловой системе появились, но ведь из QtCreator запускается же

ЗЗЫ: вставил сразу перед созданием QPluginLoader код:

Код:
    QFile x(dir.absoluteFilePath( name ));
    if(!x.open(QIODevice::ReadOnly)) QMessageBox::critical(0,"not open",dir.absoluteFilePath( name ));
    else { int s; if( ! (s = x.readAll().size()) ) QMessageBox::critical(0,"not read",dir.absoluteFilePath( name )); else
        {QFile f("plugs.txt"); f.open(QIODevice::Append); f.write((dir.absoluteFilePath( name ) + " success " +
                                                                   QString::number(s) + "\n").toAscii()); f.close();}
        x.close();}

то есть, открытие файла плагина и чтение всего файла. Ни одного сообщения об ошибке, и в plugs.txt после имен обоих проблемных плагинов написано success и полностью размеры этих файлов. То есть, успешно читаются. Проверка файловой системы тоже показывает, что на ней ошибок нет. Тупик...  Очевидно ошибка при создании объекта класса внутри плагина, но как её причину поймать, я не знаю. Непонимающий
« Последнее редактирование: Июль 01, 2015, 15:36 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #1 : Июль 01, 2015, 09:04 »

возможно банальная опечатка, во вторых попробуйте запустить экзешник вашего положения в консоли, возможно ругнется на undefined symbol (частая ошибка с плагинами при разных версиях).
еще совет, запустите qmake, полная пересборка всего проекта со всеми плагинами. да это долго, но это последняя инстанция.
зачастую мне такой подход и выручал. Еще раз внимательно пересмотрите код этих двух плагинов. попробуйте закомментировать внутреннюю реализацию и оставить только заглушку внешнего класса-плагина и посмотреть на реакцию.
кстати какая ось? под виндой не следует забывать добавлять {PLUGIN_NAME}_SHARED макросы для классов, которые должны быть видны из библиотеки.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #2 : Июль 01, 2015, 09:05 »

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

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #3 : Июль 01, 2015, 13:04 »

и еще, возможно эти плагины зависят от других плагинов или внешних библиотек, и если те не найдены, то они молча просто не загрузятся.
возможно банальная опечатка, во вторых попробуйте запустить экзешник вашего положения в консоли, возможно ругнется на undefined symbol (частая ошибка с плагинами при разных версиях).
еще совет, запустите qmake, полная пересборка всего проекта со всеми плагинами. да это долго, но это последняя инстанция.
зачастую мне такой подход и выручал. Еще раз внимательно пересмотрите код этих двух плагинов. попробуйте закомментировать внутреннюю реализацию и оставить только заглушку внешнего класса-плагина и посмотреть на реакцию.
кстати какая ось? под виндой не следует забывать добавлять {PLUGIN_NAME}_SHARED макросы для классов, которые должны быть видны из библиотеки.

Внимательней прочитайте моё первое сообщение. Проблемные плагины не зависят от каких-то сторонних библиотек - абсолютно все плагины МОИ. Используется только Qt, больше ничего. Разумеется, я в консоли и запускал - там всё тихо. При запуске приложения в QtCreator все плагины загружаются, то есть никаких undefined symbol там нет по определению (они бы не собрались компоновщиком в таком случае). Опечаток быть никаких не может - приложение читает список каталога с плагинами, и далее загружает каждый, который является динамической библиотекой.
Код:
    foreach( QString plugname, dir.entryList(QDir::Files,QDir::Name) )
    {
        if( QLibrary::isLibrary( plugname ) )
            loadPlugin( dir, plugname );
    }
Всё, включая проблемные плагины, только что было собрано из исходников одним компилятором. Что за макрос {PLUGIN_NAME}_SHARED ? Дайте ссылку, я не нашел такого в документации. Мне он зачем, если у меня наружу плагины выведены с помощью Q_EXPORT_PLUGIN2( <ИмяКлассаИнтерфейса>, <ИмяКласса > ) и Q_DECLARE_INTERFACE( <ИмяКлассаИнтерфейса>, "строка с идентификатором интерфейса" ). И еще раз: 88 плагинов, сделанных ТОЧНО ТАКЖЕ прекрасно работают.

Единственное ценное предложение - вырубать отдельные части кода проблемных плагинов. Я этим сегодня и занимаюсь, и не без успехов... Пока еще точно не могу сказать, в чем дело, но один из проблемных плагинов после отключения с помощью #if 0...#endif большей части содержимого (всё вырубить невозможно) стал загружаться.
« Последнее редактирование: Июль 01, 2015, 13:31 от Гурман » Записан

2^7-1 == 127, задумайтесь...
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #4 : Июль 01, 2015, 14:05 »

Думается мне что дело в отличии переменных окружения в креаторе от переменных окружения основной среды (ну там коммандная строка, консоль откуда запускается приложение)
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #5 : Июль 01, 2015, 14:53 »

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

Этому вероятность близка к 0. Фишка в том, что не запускающиеся плагины по сущности очень разные - один для ввода звука в буфер памяти через QAudioInput, а другой - простой одиночный виджет, наследующий QLabel (похожих на него есть еще 15 штук, наследники других QWidget - они все работают). Ничего общего в переменных окружения у них нет. Да и вообще переменные окружения я не использую. Какие переменные окружения формируются при вызове приложения из QtCreator??

Постепенно сужаю круг проблемы, но определенности нет. Нашел в одном из плагинов две функции, у обеих если закомментировать содержимое, то плагин грузится. В одной из функций нашел вызовы библиотечного метода Qt, а именно метода класса QAudioInput - если закомментировать любой из 4-х вызовов (два вызова start и два вызова stop), то плагин грузится. Но в другом методе обращения к QAudioInput закомментировать недостаточно, пока в нём еще не установил, какие вызовы влияют, там кусок кода побольше. Комментирование библиотечных вызовов влияет на размер сегмента кода, включаемого в плагин, и загружаемого в оперативную память. Поэтому есть серьезное подозрение, что проблема в распределении памяти.

ЗЫ: Плагин ввода звука грузится, если исключить использование в нём QMultimedia. То есть, любое использование QAudioInput, QAudioFormat, QAudioDeviceInfo - плагин перестёт грузиться. Но почему он грузится, когда приложение запущено в QtCreator?

Начинаю "резать" второй проблеммный плагин. Никаких обращений к QMultimedua в нём нет.
« Последнее редактирование: Июль 01, 2015, 15:24 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #6 : Июль 01, 2015, 15:36 »

Всё, понял в чём проблема... Во втором плагине ошибки вызывают вызовы SVG-графики. Они и мультимедии находятся в отдельных динамических библиотеках. То есть, правы выше были те, кто говорили и про ссылки на другие библиотеки, и про маршруты - при запуске из QtCreator эти библиотеки становятся доступны по маршруту (наверно он есть в переменных окружения, но проверять не буду). А в каталоге, где я запускаю, этих библиотек нет. Ну и проблема в диагоностике, которую выдаёт загрузчик динамических библиотек Qt - если бы он хотя бы выдал текст, что нет внешних ссылок, или что правильнее, имена библиотек, которые не может загрузить - не было бы проблемы. Но диагностика совершенно никакая.

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

Скопировал нужные библиотеки из каталога Qt в каталог запуска - всё заработало.
« Последнее редактирование: Июль 01, 2015, 15:47 от Гурман » Записан

2^7-1 == 127, задумайтесь...
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #7 : Июль 01, 2015, 18:30 »

Это да, диагностика ошибок при загрузке либ-плагинов никакая Плачущий
Записан
RovingStone
Гость
« Ответ #8 : Июль 02, 2015, 22:47 »

В Qt Creator в режиме "Проекты" можно в группе "Среда сборки" посмотреть какие переменные среды IDE устанавливает самостоятельно (ну и подкорректировать заодно). Так же и для выполнения. Авось пригодится кому..
Записан
Bepec
Гость
« Ответ #9 : Июль 02, 2015, 22:54 »

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

PS у них такая же беда с плагинами изображений и прочая. Ноль сообщений об ошибках и нерабочая программа Веселый
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #10 : Июль 03, 2015, 10:24 »

собственно мои догадки подтвердились, так как уже сталкивался с этим не раз...
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #11 : Июль 04, 2015, 22:50 »

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

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

Хотя бы в тексте сообщения QPluginLoader::errorString() выдавалось имя функции, при динамическом связывании которой возникла ошибка. Уже можно было бы догадаться в чём проблема.
Записан

2^7-1 == 127, задумайтесь...
Bepec
Гость
« Ответ #12 : Июль 04, 2015, 23:05 »

Таки да, было бы неплохо. Если б они такую же фигню засунули в свои плагины, было б ещё круче. А то при появлении пятерки я часа три решал проблему черного окна программы, при запуске на компе без плагина windows Веселый

PS хотя денежку мне эта проблема принесла, да и поиск был не такой тяжкий, но неприятно Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.069 секунд. Запросов: 22.