[PyQt] QtWebEngineWidgets crasher
Baz Walter
bazwal at ftml.net
Thu Mar 19 16:55:50 GMT 2015
On 19/03/15 05:44, Kovid Goyal wrote:
> This is a long standing issue with PyQt 5.x. See for example,
> http://www.riverbankcomputing.com/pipermail/pyqt/2014-October/034951.html
>
> The backtraces are useless, and the crash is typically random occurring
> in some fraction of starts. The only clue I have been able to get is
> that the crash happens in the QXcbEventReader thread. It does not happen
> when using a non-xcb based QPA plugin. An it never happens with pure Qt
> applications. Which tells me it is a combination of PyQt object
> lifetimes and something in the XCB QPA plugin. Unfortunately, the crash
> seems to involve stack corruption, which is why getting good backtraces
> is so difficult.
>
> Unfortunately, I am not a native code guru, so this is about where my
> knowledge ends.
Thanks for your feedback.
The description of the problem in your linked thread closely matches my
own situation. I ported a working, reliable PyQt4 application to PyQt5
without any difficulties. It was only when I tried switching from
QWebKit to QWebEngine that the issue showed up. It took me quite a while
to realize that it was *only* the QWebEngine import that made the
difference.
It's funny that you suggest making the main window an attribute of the
application object, because my application already does exactly that!
Like you say, it's relatively easy to fix the simple cases, but more
complex applications are generally much harder to deal with (and there's
no guarantee that potential fixes will last).
Your suspicions about QXcbEventReader and QPA plugins seem to match what
I'm seeing. Here's what I get from valgrind:
$ valgrind --tool=memcheck --suppressions=valgrind-python.supp python -E
-tt ./test_webeng.py
==3106== Memcheck, a memory error detector
==3106== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3106== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3106== Command: python -E -tt ./test_webeng.py
==3106==
==3109== Warning: invalid file descriptor 1024 in syscall close()
==3109== Warning: invalid file descriptor 1025 in syscall close()
==3109== Warning: invalid file descriptor 1026 in syscall close()
==3109== Warning: invalid file descriptor 1027 in syscall close()
==3109== Use --log-fd=<number> to select an alternative log fd.
==3109== Warning: invalid file descriptor 1028 in syscall close()
==3109== Warning: invalid file descriptor 1029 in syscall close()
==3109== Warning: invalid file descriptor 1030 in syscall close()
==3106== Conditional jump or move depends on uninitialised value(s)
==3106== at 0xF031A2F: ??? (in /usr/lib/libnvidia-glcore.so.304.125)
==3106== by 0x2: ???
==3106== by 0xFFEFFDAEF: ???
==3106== by 0x1F: ???
==3106== by 0xFFEFFDB3F: ???
==3106== by 0xFFEFFDB3F: ???
==3106== by 0x15B89BFF: ???
==3106== by 0x100AE67F: ???
==3106== by 0xC1D00190: ???
==3106== by 0xC1D00190: ???
==3106== by 0xF0322CB: ??? (in /usr/lib/libnvidia-glcore.so.304.125)
==3106==
==3106== Syscall param writev(vector[...]) points to uninitialised byte(s)
==3106== at 0x55CBBDD: ??? (in /usr/lib/libc-2.21.so)
==3106== by 0x104E8CCA: ??? (in /usr/lib/libxcb.so.1.1.0)
==3106== by 0x104E90C0: ??? (in /usr/lib/libxcb.so.1.1.0)
==3106== by 0x104E97E6: ??? (in /usr/lib/libxcb.so.1.1.0)
==3106== by 0x104E99B3: xcb_flush (in /usr/lib/libxcb.so.1.1.0)
==3106== by 0x11BAD7F9: QXcbWindow::hide() (qxcbwindow.cpp:793)
==3106== by 0xC941CA5: QWindow::setVisible(bool) (qwindow.cpp:507)
==3106== by 0xC34361E: QWidgetPrivate::hide_sys() (qwidget.cpp:7976)
==3106== by 0xC349913: QWidgetPrivate::hide_helper() (qwidget.cpp:7908)
==3106== by 0xC34D8EF: QWidget::setVisible(bool) (qwidget.cpp:8121)
==3106== by 0xBD04CD7: sipQWidget::setVisible(bool)
(sipQtWidgetsQWidget.cpp:1139)
==3106== by 0xC349B93:
QWidgetPrivate::close_helper(QWidgetPrivate::CloseMode) (qwidget.cpp:8250)
==3106== Address 0x11a3e571 is 4,529 bytes inside a block of size
21,144 alloc'd
==3106== at 0x4C2C080: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3106== by 0x104E866B: xcb_connect_to_fd (in /usr/lib/libxcb.so.1.1.0)
==3106== by 0x104EC120: xcb_connect_to_display_with_auth_info (in
/usr/lib/libxcb.so.1.1.0)
==3106== by 0xD3464B9: _XConnectXCB (in /usr/lib/libX11.so.6.3.0)
==3106== by 0xD3371E1: XOpenDisplay (in /usr/lib/libX11.so.6.3.0)
==3106== by 0x11B9CE26:
QXcbConnection::QXcbConnection(QXcbNativeInterface*, bool, char const*)
(qxcbconnection.cpp:332)
==3106== by 0x11BA08A3: QXcbIntegration::QXcbIntegration(QStringList
const&, int&, char**) (qxcbintegration.cpp:174)
==3106== by 0x11BB54AA: QXcbIntegrationPlugin::create(QString const&,
QStringList const&, int&, char**) (qxcbmain.cpp:50)
==3106== by 0xC928011: loadIntegration
(qplatformintegrationfactory.cpp:56)
==3106== by 0xC928011: QPlatformIntegrationFactory::create(QString
const&, QStringList const&, int&, char**, QString const&)
(qplatformintegrationfactory.cpp:73)
==3106== by 0xC933BCA: init_platform (qguiapplication.cpp:1010)
==3106== by 0xC933BCA:
QGuiApplicationPrivate::createPlatformIntegration()
(qguiapplication.cpp:1165)
==3106== by 0xC934A1C:
QGuiApplicationPrivate::createEventDispatcher() (qguiapplication.cpp:1182)
==3106== by 0x734CDCE: QCoreApplication::init()
(qcoreapplication.cpp:730)
==3106==
==3106== Thread 2 QXcbEventReader:
==3106== Jump to the invalid address stated on the next line
==3106== at 0x11B9E399: ???
==3106== by 0x15258F0F: ???
==3106== by 0x11A4B4DF: ???
==3106== by 0x15258F4F: ???
==3106== by 0x11A4B8EF: ???
==3106== by 0xFFEFFFA2E: ???
==3106== by 0x715D55D: QThreadPrivate::start(void*)
(qthread_unix.cpp:337)
==3106== by 0x741DE1F: ??? (in /usr/lib/libQt5Core.so.5.4.1)
==3106== by 0x52D5313: start_thread (in /usr/lib/libpthread-2.21.so)
==3106== Address 0x11b9e399 is not stack'd, malloc'd or (recently) free'd
==3106==
==3106==
==3106== Process terminating with default action of signal 11 (SIGSEGV)
==3106== Access not within mapped region at address 0x11B9E399
==3106== at 0x11B9E399: ???
==3106== by 0x15258F0F: ???
==3106== by 0x11A4B4DF: ???
==3106== by 0x15258F4F: ???
==3106== by 0x11A4B8EF: ???
==3106== by 0xFFEFFFA2E: ???
==3106== by 0x715D55D: QThreadPrivate::start(void*)
(qthread_unix.cpp:337)
==3106== by 0x741DE1F: ??? (in /usr/lib/libQt5Core.so.5.4.1)
==3106== by 0x52D5313: start_thread (in /usr/lib/libpthread-2.21.so)
==3106== If you believe this happened as a result of a stack
==3106== overflow in your program's main thread (unlikely but
==3106== possible), you can try to increase the size of the
==3106== main thread stack using the --main-stacksize= flag.
==3106== The main thread stack size used in this run was 8388608.
==3106==
==3106== HEAP SUMMARY:
==3106== in use at exit: 6,585,960 bytes in 28,817 blocks
==3106== total heap usage: 94,842 allocs, 66,025 frees, 18,983,597
bytes allocated
==3106==
==3106== LEAK SUMMARY:
==3106== definitely lost: 262,674 bytes in 10 blocks
==3106== indirectly lost: 0 bytes in 0 blocks
==3106== possibly lost: 714,229 bytes in 2,452 blocks
==3106== still reachable: 5,609,057 bytes in 26,355 blocks
==3106== suppressed: 0 bytes in 0 blocks
==3106== Rerun with --leak-check=full to see details of leaked memory
==3106==
==3106== For counts of detected and suppressed errors, rerun with: -v
==3106== Use --track-origins=yes to see where uninitialised values come from
==3106== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
Killed
More information about the PyQt
mailing list