我有点腌菜。
我的应用程序有一个主窗口(继承自QMainWindow
)。主窗口是QTabWidget的父窗口,QTabWidget用作一种对话框,当用户单击主窗口上的工具栏按钮时显示该对话框,并在其“关闭”时隐藏。单击按钮。此外,主窗口还有另一个工具栏按钮,单击该按钮时,会在QDialog上调用exec()。在开发应用程序时,我注意到每40次左右,单击我提到的两个按钮之一会导致出现一个空小部件,但是不是绘制了预期视图,所有内容都会冻结。当我点击“关闭”时在主窗口上的按钮,我的操作系统告诉我应用程序已停止响应。从来没有任何方法可以从这样的崩溃中恢复,我通常被迫杀死应用程序并重新启动。
关于这一切的令人头疼的事情是我无法随意重现崩溃。他们无法预测,常常让我措手不及。
我使用gdb附加到一个冻结的实例,并得到以下回溯:
#0 pthread_cond_wait@@GLIBC_2.3.2 ()
at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1 0x00007f1ba3bf1b03 in QWaitCondition::wait(QMutex*, unsigned long) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#2 0x00007f1ba3bea277 in QReadWriteLock::lockForRead() ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#3 0x00007f1b9bf5ee4e in ?? () from /opt/Qt/5.4/gcc_64/plugins/platforms/../../lib/libQt5DBus.so.5
#4 0x00007f1b9bf61d71 in ?? () from /opt/Qt/5.4/gcc_64/plugins/platforms/../../lib/libQt5DBus.so.5
#5 0x00007f1b9bf64e54 in ?? () from /opt/Qt/5.4/gcc_64/plugins/platforms/../../lib/libQt5DBus.so.5
#6 0x00007f1b904159d6 in dbus_connection_dispatch () from /lib/x86_64-linux-gnu/libdbus-1.so.3
#7 0x00007f1b9bf579f5 in ?? () from /opt/Qt/5.4/gcc_64/plugins/platforms/../../lib/libQt5DBus.so.5
#8 0x00007f1b9bfa78f5 in ?? () from /opt/Qt/5.4/gcc_64/plugins/platforms/../../lib/libQt5DBus.so.5
#9 0x00007f1ba3e5a326 in QObject::event(QEvent*) () from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#10 0x00007f1ba510b8f4 in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#11 0x00007f1ba510f506 in QApplication::notify(QObject*, QEvent*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#12 0x00007f1ba3e25c84 in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#13 0x00007f1ba3e28868 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#14 0x00007f1ba3e80123 in ?? () from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#15 0x00007f1ba283be04 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#16 0x00007f1ba283c048 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#17 0x00007f1ba283c0ec in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#18 0x00007f1ba3e80554 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)
() from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#19 0x00007f1ba3e23eab in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#20 0x00007f1ba530a2ed in QDialog::exec() () from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#21 0x0000000000425fe4 in MainWindow::AddNewDownload() ()
#22 0x00007f1ba3e57e7a in QMetaObject::activate(QObject*, int, int, void**) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#23 0x00007f1ba50fee52 in QAction::triggered(bool) () from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#24 0x00007f1ba5100c77 in QAction::activate(QAction::ActionEvent) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#25 0x00007f1ba520b0b5 in ?? () from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#26 0x00007f1ba520b374 in QAbstractButton::mouseReleaseEvent(QMouseEvent*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#27 0x00007f1ba52cf89a in QToolButton::mouseReleaseEvent(QMouseEvent*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#28 0x00007f1ba514723c in QWidget::event(QEvent*) () from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#29 0x00007f1ba52d0730 in QToolButton::event(QEvent*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#30 0x00007f1ba510b8f4 in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#31 0x00007f1ba510f071 in QApplication::notify(QObject*, QEvent*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#32 0x00007f1ba3e25c84 in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
from /opt/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#33 0x00007f1ba510df88 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) () from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#34 0x00007f1ba5162387 in ?? () from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
#35 0x00007f1ba5164e78 in ?? () from /opt/Qt/5.4/gcc_64/lib/libQt5Widgets.so.5
---Type <return> to continue, or q <return> to quit---
看来我的应用程序在满足某个条件时等待被唤醒。后面跟踪中dbus
的存在表明它正在尝试与另一个进程通信,我猜这是一个与GUI相关的进程。然而,我不知道为什么等待条件在98%的时间内得到满足,但在2%的时间内失败。使用strace
时,我能够发现被阻止的系统调用是:
futex(0x7f403c00690c, FUTEX_WAIT_PRIVATE, 1, NULL)
我在代码中没有使用QThreads
或互斥,所以我猜这个问题是Qt-internal。知道Qt低水平运作知识的人是否知道发生了什么?