PyQt:使用时偶尔出现段故障QApplication.qui应用程序

2024-10-06 07:33:42 发布

您现在位置:Python中文网/ 问答频道 /正文

注意:我也把这个贴在了PyQt邮件列表上——如果有好的答案,我会在这里回答我自己的问题。

我在执行时偶尔出现段错误 QApplication.quit(),可能与libQt5有关网络.so和/或 QtWebkit公司。在

首先,我使用的3个测试系统:

  • Arch Linux、PyQt 5.2、Qt 5.2.0、Python 3.3.3
  • ubuntu13.10,PyQt 5.0.1,Qt 5.0.2,python3.3.2
  • Windows 7、PyQt 5.2、Qt 5.2.0、Python 3.3.3

到目前为止,这些车祸对我来说从未发生过,经常发生 Ubuntu,以及不时在Windows下运行。(虽然Windows只是一个 猜猜,我就知道这个python.exe不再工作了

原始碰撞

我第一次注意到这个问题是在一个大项目中,qutebrowser, 当我在Ubuntu上输入:quit时,它给出了这个stacktrace:

#0  0xb5c296fc in QMutex::lock() () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#1  0xb3bdd97d in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#2  0xb3bdf0d0 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#3  0xb3bd4418 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#4  0xb3bd8b1e in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#5  0xb5dedf10 in QMetaObject::activate(QObject*, int, int, void**) ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#6  0xb5dee48b in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#7  0xb5e59155 in QIODevice::readyRead() ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#8  0xb3bb1f14 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#9  0xb3ba4d99 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#10 0xb3bc03bb in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#11 0xb6483a54 in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
   from /usr/lib/i386-linux-gnu/libQt5Widgets.so.5
#12 0xb6488e66 in QApplication::notify(QObject*, QEvent*) ()
   from /usr/lib/i386-linux-gnu/libQt5Widgets.so.5
#13 0xb6bb7e80 in sipQApplication::notify(QObject*, QEvent*) ()
   from /usr/lib/python3/dist-packages/PyQt5/QtWidgets.cpython-33m-i386-linux-gnu.so
#14 0xb5dc737a in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#15 0xb5e11f67 in ?? () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#16 0xb5aaf83e in g_main_context_dispatch ()
   from /lib/i386-linux-gnu/libglib-2.0.so.0
#17 0xb5aafbe8 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
#18 0xb5aafca8 in g_main_context_iteration ()
   from /lib/i386-linux-gnu/libglib-2.0.so.0
#19 0xb5e1138f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#20 0xb5dc5c06 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#21 0xb5dc6014 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#22 0xb5c2b90b in QThread::exec() ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#23 0xb5c2b99b in QThread::run() () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#24 0xb5c2fa08 in ?? () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#25 0xb7774d78 in start_thread (arg=0xa5314b40) at pthread_create.c:311
#26 0xb76ac01e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:131

Core dump here(15MB,gzip)。在

最小示例

然后我用一个最小的例子再试了一次 一秒钟后自动用QTimer。我必须循环运行 在事情发生前一分钟左右:

^{pr2}$

这给了我一个非常相似的stacktrace(在Ubuntu上):

#0  0xb6cfd8d2 in QCoreApplication::postEvent(QObject*, QEvent*, int) ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#1  0xb6d21c83 in QMetaObject::activate(QObject*, int, int, void**) ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#2  0xb6d2248b in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#3  0xb3e47935 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#4  0xb3dcf687 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#5  0xb3e483b3 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#6  0xb6d21f10 in QMetaObject::activate(QObject*, int, int, void**) ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#7  0xb6d2248b in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#8  0xb3e43fe5 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#9  0xb3d93b1e in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#10 0xb3d94630 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#11 0xb3d9471b in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#12 0xb6d21f10 in QMetaObject::activate(QObject*, int, int, void**) ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#13 0xb6d2248b in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#14 0xb6d8d155 in QIODevice::readyRead() ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#15 0xb3e09f14 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#16 0xb3dfcd99 in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#17 0xb3e183bb in ?? () from /usr/lib/i386-linux-gnu/libQt5Network.so.5
#18 0xb492ba54 in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
   from /usr/lib/i386-linux-gnu/libQt5Widgets.so.5
#19 0xb4930e66 in QApplication::notify(QObject*, QEvent*) ()
   from /usr/lib/i386-linux-gnu/libQt5Widgets.so.5
#20 0xb505fe80 in sipQApplication::notify(QObject*, QEvent*) ()
   from /usr/lib/python3/dist-packages/PyQt5/QtWidgets.cpython-33m-i386-linux-gnu.so
#21 0xb6cfb37a in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#22 0xb6d45f67 in ?? () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#23 0xb65f483e in g_main_context_dispatch ()
   from /lib/i386-linux-gnu/libglib-2.0.so.0
#24 0xb65f4be8 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
#25 0xb65f4ca8 in g_main_context_iteration ()
   from /lib/i386-linux-gnu/libglib-2.0.so.0
#26 0xb6d4536d in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#27 0xb6cf9c06 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#28 0xb6cfa014 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#29 0xb6b5f90b in QThread::exec() ()
   from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#30 0xb6b5f99b in QThread::run() () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#31 0xb6b63a08 in ?? () from /usr/lib/i386-linux-gnu/libQt5Core.so.5
#32 0xb7798d78 in start_thread (arg=0xa7812b40) at pthread_create.c:311
#33 0xb76d001e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:131

Coredump here(15MB,gzip)。在

有人知道怎么回事吗?一些神奇的东西 垃圾收集的方式不对吗?我也试过一些 PyQt4上类似症状的解决方法,但没有 也可以帮忙。在

*在描述的地方找不到StackOverflow答案-- 基本上是将QtWidgets.qApp设置为QApplication实例 运行exec_(),然后运行到None。在


Tags: infromgnulinuxlibusrintactivate
1条回答
网友
1楼 · 发布于 2024-10-06 07:33:42

我在PyQt/PySide中捕捉段故障已经有一段时间了。基本上,我发现大部分的segfaults都可以归咎于库的异步特性(因此我们也是如此)。在

对于您的确切示例,您已经将timeout信号连接到quit方法。这里可能发生的情况是,在发生超时的情况下,quit会被调用,当进程终止时,对应用程序对象的所有引用突然无效。但是当这个操作发生时,QT的事件循环仍然在运行,它试图访问它的QNetworkAccessManager来发送另一个信号,但是对该内存位置的引用已经无效,因此发生了segfault。在

在这些情况下,需要做的是实现一种关闭方法,它将确保所有操作都停止,以正确的顺序删除正在使用的QT组件,然后调用allow exiting。在

我在这里更详细地描述了这个主题,包括QtWebKit应用程序的安全关闭方法:https://github.com/integricho/path-of-a-pyqter/tree/master/qttut08

相关问题 更多 >