0

最近几天,我试图解决这个仅在 OS X 10.10 上发生的奇怪崩溃。我用属性行内的按钮稍微修改了 QtTreePropertyBrowser:


(来源:inventic.eu

这些按钮在单击时会发出信号,并且某些操作会导致清除树并再次重建它。不幸的是,这会导致崩溃。

我认为这是因为清除了信号处理中的树,但通过 QEvent 对其进行排队并没有帮助。问题是在树被清理后的某个时间有时也会发生崩溃。

所有崩溃都以这两个调用堆栈之一结束:

QTreeModel::index(QTreeWidgetItem const*, int) const + 176
QTreeModel::parent(QModelIndex const&) const + 75
QTreeView::isIndexHidden(QModelIndex const&) const + 71
QTreeView::visualRect(QModelIndex const&) const + 93
QAccessibleTableCell::rect() const + 29
QAccessibleTableCell::state() const + 146
QCocoaAccessible::hasValueAttribute(QAccessibleInterface*) + 58
[QMacAccessibilityElement accessibilityAttributeNames] + 398
NSAccessibilityEntryPointAttributeNames + 115
[NSObject(NSAccessibilityInternal) _accessibilityAttributeNamesClientError:] + 56

或者

QTreeModel::data(QModelIndex const&, int) const + 46
QAccessibleTableCell::state() const + 347
QCocoaAccessible::hasValueAttribute(QAccessibleInterface*) + 58
[QMacAccessibilityElement accessibilityAttributeNames] + 398
NSAccessibilityEntryPointAttributeNames + 115
[NSObject(NSAccessibilityInternal) _accessibilityAttributeNamesClientError:] + 

崩溃代码如下所示:


(来源:inventic.eu

根据代码,在我看来是 TreeModel 中的错误,其中一些索引在树模型被删除后没有被清除。不幸的是,我不是本地 Mac 开发人员(而是 Windows),由于 QtCreator 中的调试器没有完全工作,我无法完全理解索引出了什么问题。但根据崩溃,似乎在这两种情况下item都不是有效的指针。

有时有帮助的是在清除属性树之前将焦点设置到不同的小部件(正如我在此处描述的那样)。但此修复程序并不总是有效,有时应用程序仍然崩溃。

我已经从主应用程序中提取了所有代码并创建了最小的测试用例。我尝试了很多东西,但没有成功。

什么不起作用:

  • 在清除之前从窗口停用焦点
  • 通过使用操作创建 QEvent 在信号处理之外执行清除
  • 逐一清除属性树而不是 clear() 方法
  • 使用最新的 Qt 5.5 beta 重新编译测试项目
  • 在旧版 OS X (10.9) 上编译应用程序并在 10.10 上执行

什么工作:

  • 在 Windows / Linux 上编译相同的代码
  • 在旧版 OS X 上执行相同的代码

以下是应用程序崩溃的示例:https ://dl.dropboxusercontent.com/u/11355235/ShareX/2015-05/2015-05-21_15-28-56.mp4

执行此错误的最简单方法是清除属性树并打开任何对话框(执行可能触发崩溃的事件循环)

on_btnStandaloneDialog_clicked();
m_propertyBrowser->clear();
on_btnStandaloneDialog_clicked();

此处提供了最小的测试用例应用程序:https ://www.dropbox.com/s/dbnd3inbwpfc6l9/property-tree-crash.zip?dl=0

我会很高兴有任何想法或帮助解决这个问题(如果这里允许的话,也有付费帮助)。如果需要更多信息,请告诉我。

4

1 回答 1

0

整个问题在于 OS X 上的 Qt Accessibility 实现。

当项目树上的活动元素更改时,QAccessibleTableCell 也会更新,不幸的是,当活动元素被取消选择(索引无效)时,QAccessibleTableCell 不会更新。

由于此清除,属性树导致崩溃,因为 QAccessibleTableCell 试图访问无效数据。

我在我的博客上写了更详细的描述。

于 2015-05-25T13:20:37.717 回答