Russian Qt Forum

Qt => Qt Quick => Тема начата: ecspertiza от Сентябрь 28, 2016, 11:21



Название: Падение приложения при удалении окна
Отправлено: ecspertiza от Сентябрь 28, 2016, 11:21
Наткнулся на интересный пример. Есть qml форма, на ней кнопка. По нажатию на кнопку нужно закрыть, после чего удалить окно, вроде все просто, но приложение при этом стабильно крашится. Я упускаю какие то моменты ?

main.cpp
Код:
#include <QApplication>

#include "windowmanager.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    WindowManager manager;
    manager.showWindow();

    return a.exec();
}

windowmanager.h
Код:
#ifndef WINDOWMANAGER_H
#define WINDOWMANAGER_H

#include <QObject>
#include <QDeclarativeView>

class WindowManager : public QObject
{
    Q_OBJECT
    public:
        explicit WindowManager(QObject *parent = 0);

        void showWindow();
        Q_INVOKABLE void closeWindow();

        QDeclarativeView *window();

    private:
        QDeclarativeView *m_window;

};

#endif // WINDOWMANAGER_H


windowmanager.cpp
Код:
#include "windowmanager.h"

#include <QDeclarativeContext>

WindowManager::WindowManager(QObject *parent) : QObject(parent), m_window(0)
{
}

void WindowManager::showWindow()
{
    window()->show();
}

void WindowManager::closeWindow()
{
    m_window->close();

    if (m_window != 0) {
        delete m_window;
        m_window = 0;
    }
}

QDeclarativeView *WindowManager::window()
{
    if (m_window == 0) {
        m_window = new QDeclarativeView(0);

        m_window->rootContext()->setContextProperty("manager",this);
        m_window->setSource(QUrl("qrc:/main.qml"));
    }

    return m_window;
}

main.qml
Код:
import QtQuick 1.1

Item {
    width: 500
    height: 500

    Rectangle {
        width: 200
        height: 200

        anchors.centerIn: parent

        color: "red"

        Text {
            anchors.centerIn: parent
            color: "white"

            text: "Click for crash"
        }

        MouseArea {
            anchors.fill: parent

            onClicked: {
                manager.closeWindow();
            }
        }
    }
}


Название: Re: Падение приложения при удалении окна
Отправлено: Hellraiser от Сентябрь 28, 2016, 11:28
Можно попробовать не
Код
C++ (Qt)
delete m_window;
 
а
Код
C++ (Qt)
m_window->deleteLater();


Название: Re: Падение приложения при удалении окна
Отправлено: ecspertiza от Сентябрь 28, 2016, 11:41
Пробовал. В этом случае приложение падает не у всех пользователей. Процентов 20ть пользователей все равно при этом ловит краши.


Название: Re: Падение приложения при удалении окна
Отправлено: ecspertiza от Сентябрь 28, 2016, 11:42
Да и еще очень важный момент. Краш возникает только если кликнуть по кнопке. Если я например повешу хот кей, на закрытие и удаление окна, на туже ф-цию, все будет хорошо.


Название: Re: Падение приложения при удалении окна
Отправлено: GreatSnake от Сентябрь 28, 2016, 12:29
Коли речь идёт о закрытии приложения, то может логичнее сделать так:
cpp:
Код
C++ (Qt)
m_window->rootContext()->setContextProperty("app",qApp);
qml:
Код
Javascript
onClicked: { app.quit(); }


Название: Re: Падение приложения при удалении окна
Отправлено: ecspertiza от Сентябрь 28, 2016, 12:47
К сожалению речь не о закрытии приложения. Данный пример просто иллюстрирует проблему. Есть приложение, в котором достаточно много qml окон, одно из них выполняет определенное действие после чего закрывается и удаляется, но я никак не могу понять, почему приложение падает после удаления окна.


Название: Re: Падение приложения при удалении окна
Отправлено: GreatSnake от Сентябрь 28, 2016, 13:03
но я никак не могу понять, почему приложение падает после удаления окна.
потому что ты находясь в qml engine убиваешь сам engine, т.е. рубишь сук на котором сидишь.

Попробуй
Код
C++ (Qt)
void WindowManager::closeWindow()
{
   m_window->hide();
   m_window->deleteLater();
}


Название: Re: Падение приложения при удалении окна
Отправлено: ecspertiza от Сентябрь 28, 2016, 13:14
Согласен с тем что delete несколько жестко. Но как я уже писал выше, есть процентов 20 пользователей и только на mac os которые ловят краши и на deleteLater()

delete - просто помог локализовать проблему.


Название: Re: Падение приложения при удалении окна
Отправлено: GreatSnake от Сентябрь 28, 2016, 13:28
есть процентов 20 пользователей и только на mac os которые ловят краши и на deleteLater()
А ты уверен, что именно на нём? Что показывает backtrace в отладчике?


Название: Re: Падение приложения при удалении окна
Отправлено: ecspertiza от Сентябрь 28, 2016, 13:47
если используем deleteLater()

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

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libQt5Core.5.dylib               0x000000010bea94b5 QCoreApplication::notifyInternal(QObject*, QEvent*) + 85
1   libQt5Gui.5.dylib                0x000000010fcb64b6 QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) + 1958
2   libQt5Gui.5.dylib                0x000000010fca4e5b QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 315
3   libQt5Gui.5.dylib                0x000000010fca3123 QWindowSystemInterface::flushWindowSystemEvents() + 579
4   libqcocoa.dylib                  0x0000000111e33882 QCocoaWindow::windowShouldClose() + 34
5   libqcocoa.dylib                  0x0000000111e3ee1b -[QNSWindowDelegate windowShouldClose:] + 27
6   com.apple.AppKit                 0x00007fff94534f44 __19-[NSWindow __close]_block_invoke + 134
7   com.apple.AppKit                 0x00007fff94534e79 -[NSWindow __close] + 251
8   com.apple.AppKit                 0x00007fff94534d55 -[NSWindow _close:] + 146
9   com.apple.AppKit                 0x00007fff944e8260 -[NSApplication sendAction:to:from:] + 327
10  com.apple.AppKit                 0x00007fff944e80de -[NSControl sendAction:to:] + 86
11  com.apple.AppKit                 0x00007fff94534c4d -[NSCell _sendActionFrom:] + 128
12  com.apple.AppKit                 0x00007fff9454e655 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2316
13  com.apple.AppKit                 0x00007fff9454da27 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 487
14  com.apple.AppKit                 0x00007fff9454d13d -[NSControl mouseDown:] + 706
15  com.apple.AppKit                 0x00007fff949e4831 -[_NSThemeWidget mouseDown:] + 304
16  com.apple.AppKit                 0x00007fff944cea58 -[NSWindow sendEvent:] + 11296
17  libqcocoa.dylib                  0x0000000111e2f0a7 -[QNSWindow superSendEvent:] + 39
18  libqcocoa.dylib                  0x0000000111e2eaf7 -[QNSWindowHelper handleWindowEvent:] + 423
19  com.apple.AppKit                 0x00007fff9446d5d4 -[NSApplication sendEvent:] + 2021
20  libqcocoa.dylib                  0x0000000111e455ce -[QNSApplication sendEvent:] + 78
21  com.apple.AppKit                 0x00007fff942bd9f9 -[NSApplication run] + 646
22  libqcocoa.dylib                  0x0000000111e41e64 QCocoaEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 2420
23  libQt5Core.5.dylib               0x000000010bea6a0e QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 398
24  libQt5Core.5.dylib               0x000000010bea9a87 QCoreApplication::exec() + 359


Если мы не удаляем окно, не важно как delete или deletaLater() ошибки не возникает. Но если используем delete ошибка возникает у всех и сразу. Возникает вопрос, как правильно было удалять окно, через сигналы\слоты поведение тоже не предсказуемо.


Название: Re: Падение приложения при удалении окна
Отправлено: ecspertiza от Сентябрь 28, 2016, 13:56
Видимо проблема со событийной системе. То есть приложение добавляет некоторое событие в очередь, после delete убивается получатель. Но при этом попадает в notify где уже и происходит краш. Но почему, все же есть краши при deleteLater() не понятно, ведь он должен это учитывать. При этом, краши у небольшого круга людей.


Название: Re: Падение приложения при удалении окна
Отправлено: Hellraiser от Сентябрь 28, 2016, 14:02
Можно попробовать грязный хак:
Код
C++ (Qt)
QTimer::singleShot(1000, m_window, SLOT(deleteLater()));
или перед deleteLater() вызвать
Код
C++ (Qt)
m_window->disconnect();


Название: Re: Падение приложения при удалении окна
Отправлено: Igors от Сентябрь 28, 2016, 14:17
..через сигналы\слоты поведение тоже не предсказуемо.
Может все-таки стоит проверить сигнал с QueuedConnection соединенный со слотом-убийцей


Название: Re: Падение приложения при удалении окна
Отправлено: ecspertiza от Сентябрь 29, 2016, 12:44
Код:
QTimer::singleShot(1000, m_window, SLOT(deleteLater()));

Не сработал

QueuedConnection проверил, тоже не прокатило. При этом вызов функции удаления через keyPress каким то хоткеем отрабатывает хорошо. При этом не важно, какой из методов использовать и delete работает и deleteLater и все эти извращения с таймером :-)


Название: Re: Падение приложения при удалении окна
Отправлено: GreatSnake от Сентябрь 29, 2016, 13:02
При этом вызов функции удаления через keyPress каким то хоткеем отрабатывает хорошо.
А кем и как keyPress обрабатывается?


Название: Re: Падение приложения при удалении окна
Отправлено: ecspertiza от Сентябрь 29, 2016, 13:10
Есть класс SurfaceWindow унаследован от QDeclarativeView в нем переопределен keyPressEvent()

есть некая функция допустим foo(), так вот и кнопка в qml и keyPressEvent() дергают эту функцию, после чего происходит закрытие и удаление формы. Удаляю ее так как она достаточно тяжелая и не очень хочется занимать место в памяти.

Далее идет различное поведение, на всех Windows и Linux машинах работает хорошо, под mac os есть некоторый процент машин на котором после этого падает. Общее количество пользователей приложения большое. По этому если бы где то еще была такая проблема, точно знали бы.



Название: Re: Падение приложения при удалении окна
Отправлено: ecspertiza от Октябрь 03, 2016, 12:38
В продолжение темы. Решил по убирать все delete и deleteLater(), ну вдруг где то есть баг. Для формы оставил только close(), но при этом выставил атрибут Qt::WA_DeleteOnClose. Теперь приложение крашилось сразу после закрытия, при тех же условиях, только под маками. Сделал следующее, перенес удаление окна непосредственно перед вызовом show(). То есть, перед показом, я проверяю есть ли указатель или нет, если есть, удаляю и создаю новый. Наверное не лучшее архитектурное решение, но оно работает :-)


Название: Re: Падение приложения при удалении окна
Отправлено: OKTA от Ноябрь 05, 2016, 04:01
У меня похожим образом на уничтожении QDeclarativeView крашится. Причем тоже абсолютно рандомно. Правда у меня вьюха встраивается в обычный лэйаут.
Чтобы не крашилось, перед уничтожением зануляю родителя у вьюхи и удаляю через deleteLater, тогда все норм. А если с родителем, то крашится.