Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: vulko от Апрель 07, 2014, 14:37



Название: SIGSEGV при отрисовке QWidget'ов
Отправлено: vulko от Апрель 07, 2014, 14:37
Коллеги, нужен хелп!

Целый день пытаюсь понять причину, никак не могу.

Есть приложение, QGraphicsScene с QGLWidget в качестве ViewPort, в нём в фоне рисуется opengl сцена, сверху несколько виджетов наследующихся от QDialog.

Сменил отрисовку с glBegin/glEnd на VBO (vertex buffer array), и теперь всё отваливается в разных местах - вызов QPushButton::paintEvent(event) в аналогичном методе потомка.
Убрал, падает в paintEvent наследника QDialog на вызове painter.drawText... И так далее...
Причем все указатели живые.

Когда убрал все paintEvent'ы, падает в левом коде вообще (qt или opengl). Постоянно SIGSEGV.

Пробовал запускать valgrind, с valgrind'ом всё работает и не падает нифига...

Qt 4.8.3, GLEW, GLX.


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: vizir.vs от Апрель 07, 2014, 14:50
А gdb не пробовал юзать?


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: Swa от Апрель 07, 2014, 15:02
Попробуйте внимательно прочитать документацию по QGLWidget http://qt-project.org/doc/qt-4.8/qglwidget.html (http://qt-project.org/doc/qt-4.8/qglwidget.html), наверняка вы пропустили что-то важное.


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: vulko от Апрель 07, 2014, 15:02
А gdb не пробовал юзать?

насколько я понял, gdb это стандартный дебаггер. пока гуглил наткнулся на команду gdb appname dumpfilename, но она кидает меня в gdb консоль...
а на дебаге видно конечно крэш стэки, но толку от них... там из них только один мой вызов, int main()... :)

но самое интересное в том, что всё прекрасно работало и рисовалось без крешей... но вечером прошлой пятницы вдруг всё стало вылетать. сначала думал что это результат обновления некоторых пакетов, связанных как раз с GL и дровами видюхи...

однако сегодня после запуска бэкапнутой виртуалки, всё то же самое. код весь уже облазил, никаких ошибок не вижу.
более того, все gl вызовы отрабатывают как надо, однако вызов glDrawArrays приводит к SIGSEGV, а вот вызов glDrawElements нет. Правда и не отрисовывает ничего...


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: vulko от Апрель 07, 2014, 15:24
Попробуйте внимательно прочитать документацию по QGLWidget http://qt-project.org/doc/qt-4.8/qglwidget.html (http://qt-project.org/doc/qt-4.8/qglwidget.html), наверняка вы пропустили что-то важное.

Глянул, ничего что могло бы мне помочь. В общем то я и не пользую напрямую QGLWidget, я всего лишь задаю его как viewPort для QGraphicsScene.

Для наглядности крэш стэк, всё случается после того как в мейне QT вызывает QPainter::drawText, который после нескольких вызовов падает внутри swrast_dri.so. Причем это именно QT вызов, а не мой!

Код:
Thread 1 (Thread 0x7ffff7fce780 (LWP 13599)):
#0  0x00007fffecec64f8 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#1  0x00007fffecece4c0 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#2  0x00007fffecec7170 in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#3  0x00007fffecec74ac in ?? () from /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so
#4  0x00007ffff767a88a in ?? () from /usr/lib/x86_64-linux-gnu/libQtOpenGL.so.4
#5  0x00007ffff767be8e in QGL2PaintEngineEx::drawTextItem(QPointF const&, QTextItem const&) () from /usr/lib/x86_64-linux-gnu/libQtOpenGL.so.4
#6  0x00007ffff6c60d56 in QPainter::drawTextItem(QPointF const&, QTextItem const&) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#7  0x00007ffff6d6cd7a in QTextLine::draw(QPainter*, QPointF const&, QTextLayout::FormatRange const*) const () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#8  0x00007ffff6c640e6 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#9  0x00007ffff6c6502b in QPainter::drawText(QRect const&, int, QString const&, QRect*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#10 0x00007ffff6e00b84 in QStyle::drawItemText(QPainter*, QRect const&, int, QPalette const&, bool, QString const&, QPalette::ColorRole) const () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#11 0x00007ffff6e1fa20 in QCommonStyle::drawControl(QStyle::ControlElement, QStyleOption const*, QPainter*, QWidget const*) const () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#12 0x00007ffff6eaf6ce in QWindowsStyle::drawControl(QStyle::ControlElement, QStyleOption const*, QPainter*, QWidget const*) const () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#13 0x00007ffff6e46c7f in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#14 0x00007ffff6e2159e in QCommonStyle::drawControl(QStyle::ControlElement, QStyleOption const*, QPainter*, QWidget const*) const () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#15 0x00007ffff6eaf6ce in QWindowsStyle::drawControl(QStyle::ControlElement, QStyleOption const*, QPainter*, QWidget const*) const () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#16 0x00007ffff6e44f9e in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#17 0x00007ffff6f542a2 in QPushButton::paintEvent(QPaintEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#18 0x00007ffff6b58a92 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#19 0x00007ffff6b091ac in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#20 0x00007ffff6b0d62a in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#21 0x00007ffff62906be in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#22 0x00007ffff6b547a4 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#23 0x00007ffff6b5529f in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#24 0x00007ffff6b550e4 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#25 0x00007ffff6b550e4 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#26 0x00007ffff6b550e4 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#27 0x00007ffff6b54335 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#28 0x00007ffff6b56db1 in QWidgetPrivate::render(QPaintDevice*, QPoint const&, QRegion const&, QFlags<QWidget::RenderFlag>, bool) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#29 0x00007ffff6b57079 in QWidget::render(QPaintDevice*, QPoint const&, QRegion const&, QFlags<QWidget::RenderFlag>) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#30 0x00007ffff6b57a08 in QWidget::render(QPainter*, QPoint const&, QRegion const&, QFlags<QWidget::RenderFlag>) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#31 0x00007ffff70e847b in QGraphicsProxyWidget::paint(QPainter*, QStyleOptionGraphicsItem const*, QWidget*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#32 0x00007ffff70ed349 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#33 0x00007ffff70ffcf5 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#34 0x00007ffff7102648 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#35 0x00007ffff7102d05 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#36 0x00007ffff71037de in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#37 0x00007ffff711fb68 in QGraphicsView::paintEvent(QPaintEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#38 0x00007ffff6b58a92 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#39 0x00007ffff6f08df6 in QFrame::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#40 0x00007ffff7120c9b in QGraphicsView::viewportEvent(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#41 0x00007ffff6290826 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#42 0x00007ffff6b0917c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#43 0x00007ffff6b0d62a in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#44 0x00007ffff62906be in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#45 0x00007ffff6b547a4 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#46 0x00007ffff6d1eaec in QWidgetPrivate::repaint_sys(QRegion const&) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#47 0x00007ffff6b8643a in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#48 0x00007ffff6b8744b in QApplication::x11ProcessEvent(_XEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#49 0x00007ffff6baf462 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#50 0x00007ffff3a49355 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#51 0x00007ffff3a49688 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#52 0x00007ffff3a49744 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#53 0x00007ffff62bef96 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#54 0x00007ffff6baf0de in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#55 0x00007ffff628f40f in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#56 0x00007ffff628f698 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#57 0x00007ffff6294ab8 in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#58 0x000000000040af59 in main (argc=1, argv=0x7fffffffe8f8) at main.cpp:10


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: Swa от Апрель 07, 2014, 15:46
Если приведете минимальный код, на котором воспроизводится проблема, могу вечером дома посмотреть.


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: vulko от Апрель 08, 2014, 08:43
Если приведете минимальный код, на котором воспроизводится проблема, могу вечером дома посмотреть.

https://drive.google.com/file/d/0BzPSabsrRNz_dm01eEZ2TUt2YmM/edit?usp=sharing

проблема из-за вот этого вызова:
void oglDrawHelper::drawRadialGrid()

Там собсно и происходит отрисовка с помощью glDrawArrays. Если вызов убрать, апликейшн не падает.


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: Swa от Апрель 08, 2014, 09:01
Ваш код не компилируется
Код:
LocatorDemo\TrackingManager\datamodel.h:4: error: DataHandler/datamessage.h: No such file or directory
LocatorDemo\TrackingManager\trackingcontroller.h:6: error: DataHandler/incomingdatahandler.h: No such file or directory
итд


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: vulko от Апрель 08, 2014, 09:38
Ваш код не компилируется
Код:
LocatorDemo\TrackingManager\datamodel.h:4: error: DataHandler/datamessage.h: No such file or directory
LocatorDemo\TrackingManager\trackingcontroller.h:6: error: DataHandler/incomingdatahandler.h: No such file or directory
итд

Перезалил, всё должно работать:
https://drive.google.com/file/d/0BzPSabsrRNz_bEVTZ2M5TkFMdWs/edit?usp=sharing


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: vulko от Апрель 08, 2014, 10:11
omg... дело продвинулось. случайным образом выяснилось, что если дебажить инициализацию вертексных буферов и gl функций для работы с ними, то всё отлично работает.

поставил после создания VBO слип на 1 секунду, прекрасно работает.

походу вертексные буферы копируются в память в отдельном потоке, и т.к. отрисовка начинается до завершения копирования... хотя конечно странно что копирование такое долгое.
опытным путем выяснил что 500мс примерно уходит на это...
хотя это лишь идея и возможно я не прав. какие у вас соображения?


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: Swa от Апрель 08, 2014, 10:51
Попробуйте вызвать GlGetError во время рендеринга.


Название: Re: SIGSEGV при отрисовке QWidget'ов
Отправлено: vulko от Апрель 08, 2014, 11:28
Попробуйте вызвать GlGetError во время рендеринга.

glgeterror выдает GL_NOERROR