Russian Qt Forum

Qt => Общие вопросы => Тема начата: QCasper от Март 30, 2007, 09:41



Название: зависает QPluginLoader::unload()
Отправлено: QCasper от Март 30, 2007, 09:41
У меня есть плагин, который выполняет определенные действия (они связаны с передачей данных по http). Так вот если просто загрузить плагин, то он нормально выгружается. А если загрузить, дать ему пораобтать, остановить его работу, то программа зависает на QPluginLoader::unload(), управление из этой ф-ции просто не возвращется. Такое ощущение, что там где-то на бесконечный цикл натыкается программа. Из-за чего это теоретически может происходить?


Название: зависает QPluginLoader::unload()
Отправлено: Admin от Март 30, 2007, 11:04
1) плагин треды создает?
2) сокет точно закрывается?
3) редко - стек нарушается


Название: зависает QPluginLoader::unload()
Отправлено: QCasper от Март 30, 2007, 12:22
Цитата: "Admin"
1) плагин треды создает?
2) сокет точно закрывается?
3) редко - стек нарушается


1) Нет.
2) Как например? в деструкторе делаю http->abort()
3) это как понять и как бороться? у меня довольно часто возникает.


Название: зависает QPluginLoader::unload()
Отправлено: Tonal от Март 30, 2007, 16:30
А если стопнуть и стек посмотреть?


Название: зависает QPluginLoader::unload()
Отправлено: QCasper от Март 31, 2007, 17:18
Цитата: "Tonal"
А если стопнуть и стек посмотреть?


    ntdll.dll!7c90eb94()    
    ntdll.dll!7c90e9c0()    
    kernel32.dll!7c8025db()    
>   QtCored4.dll!QBasicAtomic::testAndSetAcquire(int expected=2088773128, int newval=0)  Line 96 + 0x18   C++
    kernel32.dll!7c8399f3()    
    kernel32.dll!7c802542()    
    QtCored4.dll!QThread::wait(unsigned long time=4294967295)  Line 406 + 0x11   C++
    QtNetworkd4.dll!QHostInfoAgent::cleanup()  Line 129   C++
    QtNetworkd4.dll!QHostInfoAgent::~QHostInfoAgent()  Line 89 + 0x34   C++
    QtNetworkd4.dll!QHostInfoAgent::`scalar deleting destructor'()  + 0xf   C++
    QtNetworkd4.dll!QGlobalStatic<QHostInfoAgent>::~QGlobalStatic<QHostInfoAgent>()  Line 1332 + 0x21   C++
    QtNetworkd4.dll!$E2()  + 0xd   C++
    QtNetworkd4.dll!_CRT_INIT(void * hDllHandle=0x64000000, unsigned long dwReason=0, void * lpreserved=0x00000000)  Line 234   C
    QtNetworkd4.dll!_DllMainCRTStartup(void * hDllHandle=0x64000000, unsigned long dwReason=0, void * lpreserved=0x00000000)  Line 288 + 0x11   C
    ntdll.dll!7c9011a7()    
    ntdll.dll!7c91e6f4()    
    msvcr71d.dll!_free_base(void * pBlock=0x00000000)  Line 103   C
    msvcr71d.dll!_free_dbg_lk(void * pUserData=, int nBlockUse=)  Line 1207 + 0x9   C

добавлено спустя 5 минут:

 Кстати когда паузил дебаг мне вывалилась табличка:
"The process appears to be deadlocked (or is not running any user-mode code). All threads have been stopped."


Название: зависает QPluginLoader::unload()
Отправлено: Tonal от Март 31, 2007, 19:09
QHostInfoAgent - наследник QThread.
Так что неявно твой плагин создаёт таки поток.
И висит именно в его деструкторе...

Попробуй http->abort() сделать явно, до выгрузки плагина...


Название: зависает QPluginLoader::unload()
Отправлено: QCasper от Март 31, 2007, 20:27
Цитата: "Tonal"
QHostInfoAgent - наследник QThread.
Так что неявно твой плагин создаёт таки поток.
И висит именно в его деструкторе...

Попробуй http->abort() сделать явно, до выгрузки плагина...


Ну то что неявно он создает поток то понятно, я же говорю QHttp использую. Я имел ввиду я сам поток не создаю.


Название: зависает QPluginLoader::unload()
Отправлено: Tonal от Апрель 01, 2007, 15:53
Разницы нет, сам ты поток создаёшь, или ещё кто-то.
Главное, что он создаётся и то, что в в стартовой функции Dll нельзя вызывать функции ожидания (см у Рихтера "Как система упорядочивает вызовы DIIMain").
Так что выход один: позаботиться о том, чтобы на момент выгрузки никакие потоки не завершались.
Т.е. надо стопать коннект до выгрузки.


Название: зависает QPluginLoader::unload()
Отправлено: QCasper от Апрель 01, 2007, 16:54
Цитата: "Tonal"
Разницы нет, сам ты поток создаёшь, или ещё кто-то.
Главное, что он создаётся и то, что в в стартовой функции Dll нельзя вызывать функции ожидания (см у Рихтера "Как система упорядочивает вызовы DIIMain").
Так что выход один: позаботиться о том, чтобы на момент выгрузки никакие потоки не завершались.
Т.е. надо стопать коннект до выгрузки.


чем стопить лучше qhttp? abort? close?

добавлено спустя 13 минут:

 Не помогает abort() :( Вызываю вручную, нажатием на кнопку. А потом только удаляю объект.


Название: зависает QPluginLoader::unload()
Отправлено: QCasper от Апрель 04, 2007, 10:49
Я тут заметил одну вещь. Если сразу не пытаться выгружать плагин, а дождаться пока не завершаться три каких-то потока, это видно в output во время debag'a в VS, то плагин выгружается нормально. В связи с этим у меня вопрос, можно ли как-то получить эти потоки и насильно их замочить? Причем могу уверенно сказать, что http коннекта к хосту точно нет. То есть сначала я вижу сигнал stateChanged(state) где state == 0 (Unconnected), а только через время, вижу в аутпуте как эти три потока завершаются.


Название: зависает QPluginLoader::unload()
Отправлено: Tonal от Апрель 05, 2007, 12:09
Попробуй до загрузки плагина создать подключение - а удалить после.
Может поможет.
А вообще-то, надо делать минимальный пример и писать Тролям.


Название: зависает QPluginLoader::unload()
Отправлено: QCasper от Апрель 17, 2007, 15:52
Цитата: "Tonal"
Попробуй до загрузки плагина создать подключение - а удалить после.
Может поможет.
А вообще-то, надо делать минимальный пример и писать Тролям.


Здрасьте, а как это, у меня плагин отвечает за подключение, приложение и не знает даже чем там он занимается :) Оно только загружает его, говорит: "работай давай", потом говорит: "все, хорош", и выгружает его :)


Название: зависает QPluginLoader::unload()
Отправлено: Tonal от Апрель 19, 2007, 13:25
Можно так извратиться:
1) приложение загружает плагин
2) плагин говорит приложению - инициализируй мине сеточку
3) приложение инициализирует
4) плагин работает
5) приложение выгружает плагин
Вот здесь приложение может стопнуть сеть...


Название: зависает QPluginLoader::unload()
Отправлено: QCasper от Апрель 23, 2007, 14:19
Цитата: "Tonal"
Можно так извратиться:
1) приложение загружает плагин
2) плагин говорит приложению - инициализируй мине сеточку
3) приложение инициализирует
4) плагин работает
5) приложение выгружает плагин
Вот здесь приложение может стопнуть сеть...


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