Bug 15792 - Проблемы в обработке событий при удаление самого объекта.
Summary: Проблемы в обработке событий при удаление самого объекта.
Status: CLOSED FIXED
Alias: None
Product: Sisyphus
Classification: Development
Component: qt4 (show other bugs)
Version: unstable
Hardware: all Linux
: P2 normal
Assignee: Sergey V Turchin
QA Contact: qa-sisyphus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-05-26 21:38 MSD by Roman Savochenko
Modified: 2008-09-30 12:23 MSD (History)
3 users (show)

See Also:


Attachments
Программа демонстрации проблемы (15.68 KB, application/octet-stream)
2008-05-26 21:45 MSD, Roman Savochenko
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Roman Savochenko 2008-05-26 21:38:03 MSD
Неоднократно замечены проблемы с перекрытием в обработке событий/сигналов и 
удаления объекта с этими обработчиками.

На QT4.4 он начал предупреждать о подобном:
QObject: Do not delete object, 'unnamed', during its event handler!

Но не понятно другое, как это возможно в одном потоке и как это разруливать?
Ситуация достаточно неочевидна и перестройкой пользовательского кода часто не 
лечится или лечится только путём потери функциональности.

Например ситуация:
- инспектор атрибутов генерирует сигнал на обновления виджета при потере 
фокуса; в процессе обновления удаляется вложенный виджет и вместо него 
создаётся новый;
- в тоже время фокус теряется по причине выбора этого самого виджета 
(удаляемого), т.е. какие-то события пошли к нему;
- в результате генерируется "QObject: Do not delete object, 'unnamed', during 
its event handler!" и происходит обрушение.

Я не понимаю как такое может вообще происходить, разве в деструкторе не 
откидываются из очереди события к удаляемому виджету?

Порылся в коде QT4.4 и меня насторожил вот этот участок кода в функции 
QCoreApplication::notifyInternal( ) файла qcoreapplication.cpp:
    bool returnValue;
    try {
        returnValue = notify(receiver, event);
    } catch(...) {
        --threadData->loopLevel;
        throw;
    }
Получается при возникновении исключения оно передаётся на уровень выше, а флаг 
d->inEventHandler не очищается, что и является причиной указанного сообщения, а 
установка этого флага осуществляется только там. Не исключено, что не очищается 
ещё чего нибуть.
Comment 1 Roman Savochenko 2008-05-26 21:45:26 MSD
Created attachment 2645 [details]
Программа демонстрации проблемы

Подготовил наглядный пример этой проблемы на основе примера из дистрибутива
QT4.4 - basiclayouts. Для кнопки Button1 добавил eventFilter() c целью отлова
потери фокуса. По результату потери фокуса удаляется кнопка Button2. Так вот,
если сначала нажать кнопку Button1, а затем Button3, то кнопка Button2
корректно удалится, а вот если после Button1 нажать Button2, то программа
упадёт по этой самой проблеме.
Comment 2 Michael Shigorin 2008-05-31 02:43:48 MSD
alterator-browser-qt - X11 Qt interface driver for alterator            
* Fri May 30 2008 Sergey V Turchin <zerg@altlinux> 2.9.83-alt1                 
                    
- fix #15792
* Fri May 30 2008 Sergey V Turchin <zerg@altlinux> 2.9.82-alt1
- fix *listbox state-rows attribute  
- force return *multi*listbox current-rows and state-rows if empty list
* Thu May 29 2008 Sergey V Turchin <zerg@altlinux> 2.9.81-alt1
Comment 3 Sergey V Turchin 2008-06-02 17:26:37 MSD
Я не уверен, это бага Qt или нет, но можно использовать deleteLater
Comment 4 Roman Savochenko 2008-06-02 17:56:29 MSD
Это не всегда возможно.
У меня был случай с QAbstractItemView::itemDelegate()
Когда я создаю в качестве элемента редактирования комбобокс(редактируемый) и 
добавляю ему обработку события принятия выбора по выбору элемента.
Так вот, если я редактирую содержимое этого комбобокса руками и нажимаю Enter, 
то приходит два события и он валится поскольку сама QT удалила этот элемент 
после первого события.

Кроме того, на динамических интерфейсах, где элементы часто создаются и 
удаляются это неизбежно будет и проблему просто так не обойдёшь.
Comment 5 Sergey V Turchin 2008-06-10 17:27:30 MSD
Похоже, в Trolltech думают, что это фича
http://trolltech.net/developer/task-tracker/index_html?method=entry&id=198093
http://trolltech.de/developer/task-tracker/index_html?method=entry&id=205903
Comment 6 Roman Savochenko 2008-06-24 00:14:37 MSD
Если бы оно только писало и не падало.
В приложенном примере нет моего кода, а оно устойчиво падает на банальной ситуации.
Comment 7 Roman Savochenko 2008-09-21 15:46:25 MSD
Подскажите адрес официального багтрекера QT. Запощу эту багу прямо им.
Comment 8 Andrey Rahmatullin 2008-09-21 15:55:34 MSD
(In reply to comment #7)
> Подскажите адрес официального багтрекера QT. Запощу эту багу прямо им.
> 

http://trolltech.com/developer/task-tracker
Comment 9 Roman Savochenko 2008-09-30 12:22:53 MSD
Остановились на deleteLater
Закрываю