Commit fbb955c7 authored by Gleb Popov's avatar Gleb Popov 💬

Workaround the bug found by ASan, which can be seen on FreeBSD CI.

Summary:
Currently many tests fail (at least on FreeBSD) with ASan turned on. This is what happening:

- `test_toolviewtoolbar` creates an action, a `ToolDocument` and a `View` in the `init()` function.
- `ToolViewAction` registers itself as event filter for the created `View`.
- When `cleanup` is called, the controller gets deleted. This causes removal of its children (`QObject::deleteChildren()`), included the mentioned `View`.
- Somewhere later during destruction, some `QEvent` arrives and gets passed to `ToolViewAction::eventFilter()`. This function accesses `->widget()` method of `m_dock->view()`, but that `View` is already deleted, which causes ASan error.

Note that adding `removeEventFilter()` to `ToolViewAction::~ToolViewAction()` doesn't solve the problem - the event arrival happens before `ToolViewAction` destruction.

Full ASan report:

```
********* Start testing of TestToolViewToolBar *********
Config: Using QtTest library 5.12.0, Qt 5.12.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by Clang 6.0.1 (tags/RELEASE_601/final 335540))
PASS   : TestToolViewToolBar::initTestCase()
=================================================================
==21936==ERROR: AddressSanitizer: heap-use-after-free on address 0x6030000958a0 at pc 0x000800465e5a bp 0x7fffffffd230 sp 0x7fffffffd228
READ of size 8 at 0x6030000958a0 thread T0
    #0 0x800465e59 in QScopedPointer<Sublime::ViewPrivate, QScopedPointerDeleter<Sublime::ViewPrivate> >::operator->() const /usr/local/include/qt5/QtCore/qscopedpointer.h:118:16
    #1 0x80046352f in Sublime::View::widget(QWidget*) /home/arr/projects/kdevelop/kdevplatform/sublime/view.cpp:76:10
    #2 0x800498c53 in ToolViewAction::eventFilter(QObject*, QEvent*) /home/arr/projects/kdevelop/kdevplatform/sublime/idealbuttonbarwidget.cpp:85:40
    #3 0x802027193 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) (/usr/local/lib/qt5/libQt5Core.so.5+0x427193)
    #4 0x80127decb in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/local/lib/qt5/libQt5Widgets.so.5+0x27decb)
    #5 0x80127f27c in QApplication::notify(QObject*, QEvent*) (/usr/local/lib/qt5/libQt5Widgets.so.5+0x27f27c)
    #6 0x802026ef0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/local/lib/qt5/libQt5Core.so.5+0x426ef0)
    #7 0x802051020 in QObjectPrivate::setParent_helper(QObject*) (/usr/local/lib/qt5/libQt5Core.so.5+0x451020)
    #8 0x802050c11 in QObject::~QObject() (/usr/local/lib/qt5/libQt5Core.so.5+0x450c11)
    #9 0x801e4762e in QAbstractAnimation::~QAbstractAnimation() (/usr/local/lib/qt5/libQt5Core.so.5+0x24762e)
    #10 0x801e4cfa4 in QPropertyAnimation::~QPropertyAnimation() (/usr/local/lib/qt5/libQt5Core.so.5+0x24cfa4)
    #11 0x802051461 in QObject::event(QEvent*) (/usr/local/lib/qt5/libQt5Core.so.5+0x451461)
    #12 0x80127dee0 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/local/lib/qt5/libQt5Widgets.so.5+0x27dee0)
    #13 0x80127f27c in QApplication::notify(QObject*, QEvent*) (/usr/local/lib/qt5/libQt5Widgets.so.5+0x27f27c)
    #14 0x802026ef0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/local/lib/qt5/libQt5Core.so.5+0x426ef0)
    #15 0x802027db8 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (/usr/local/lib/qt5/libQt5Core.so.5+0x427db8)
    #16 0x800323331  (/usr/local/lib/qt5/libQt5Test.so.5+0x1e331)
    #17 0x800323bee  (/usr/local/lib/qt5/libQt5Test.so.5+0x1ebee)
    #18 0x800324988  (/usr/local/lib/qt5/libQt5Test.so.5+0x1f988)
    #19 0x80032517b in QTest::qRun() (/usr/local/lib/qt5/libQt5Test.so.5+0x2017b)
    #20 0x800324ef3 in QTest::qExec(QObject*, int, char**) (/usr/local/lib/qt5/libQt5Test.so.5+0x1fef3)
    #21 0x2b97fb in main /home/arr/projects/kdevelop/kdevplatform/sublime/tests/test_toolviewtoolbar.cpp:144:1

0x6030000958a0 is located 16 bytes inside of 24-byte region [0x603000095890,0x6030000958a8)
freed by thread T0 here:
    #0 0x2b51f2 in operator delete(void*) /usr/src/contrib/compiler-rt/lib/asan/asan_new_delete.cc:149:3
    #1 0x800463371 in Sublime::View::~View() /home/arr/projects/kdevelop/kdevplatform/sublime/view.cpp:61:1
    #2 0x802050de9 in QObjectPrivate::deleteChildren() (/usr/local/lib/qt5/libQt5Core.so.5+0x450de9)
    #3 0x802050bf0 in QObject::~QObject() (/usr/local/lib/qt5/libQt5Core.so.5+0x450bf0)
    #4 0x80041a3be in Sublime::Document::~Document() /home/arr/projects/kdevelop/kdevplatform/sublime/document.cpp:73:21
    #5 0x8004626de in Sublime::ToolDocument::~ToolDocument() /home/arr/projects/kdevelop/kdevplatform/sublime/tooldocument.cpp:48:29
    #6 0x800462708 in Sublime::ToolDocument::~ToolDocument() /home/arr/projects/kdevelop/kdevplatform/sublime/tooldocument.cpp:48:29
    #7 0x802050de9 in QObjectPrivate::deleteChildren() (/usr/local/lib/qt5/libQt5Core.so.5+0x450de9)
    #8 0x802050bf0 in QObject::~QObject() (/usr/local/lib/qt5/libQt5Core.so.5+0x450bf0)
    #9 0x800405d9a in Sublime::Controller::~Controller() /home/arr/projects/kdevelop/kdevplatform/sublime/controller.cpp:113:1
    #10 0x800405dc8 in Sublime::Controller::~Controller() /home/arr/projects/kdevelop/kdevplatform/sublime/controller.cpp:111:1
    #11 0x2b82af in TestToolViewToolBar::cleanup() /home/arr/projects/kdevelop/kdevplatform/sublime/tests/test_toolviewtoolbar.cpp:88:5
    #12 0x2bef0c in TestToolViewToolBar::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/arr/projects/kdevelop/build/kdevplatform/sublime/tests/test_toolviewtoolbar_autogen/EWIEGA46WW/moc_test_toolviewtoolbar.cpp:85:21
    #13 0x8020320ce in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (/usr/local/lib/qt5/libQt5Core.so.5+0x4320ce)
    #14 0x800323318  (/usr/local/lib/qt5/libQt5Test.so.5+0x1e318)
    #15 0x800323bee  (/usr/local/lib/qt5/libQt5Test.so.5+0x1ebee)
    #16 0x800324988  (/usr/local/lib/qt5/libQt5Test.so.5+0x1f988)
    #17 0x80032517b in QTest::qRun() (/usr/local/lib/qt5/libQt5Test.so.5+0x2017b)
    #18 0x800324ef3 in QTest::qExec(QObject*, int, char**) (/usr/local/lib/qt5/libQt5Test.so.5+0x1fef3)
    #19 0x2b97fb in main /home/arr/projects/kdevelop/kdevplatform/sublime/tests/test_toolviewtoolbar.cpp:144:1

previously allocated by thread T0 here:
    #0 0x2b4612 in operator new(unsigned long) /usr/src/contrib/compiler-rt/lib/asan/asan_new_delete.cc:92:3
    #1 0x80041b02e in Sublime::Document::newView(Sublime::Document*) /home/arr/projects/kdevelop/kdevplatform/sublime/document.cpp:117:21
    #2 0x80041a604 in Sublime::Document::createView() /home/arr/projects/kdevelop/kdevplatform/sublime/document.cpp:82:18
    #3 0x2b6eac in TestToolViewToolBar::init() /home/arr/projects/kdevelop/kdevplatform/sublime/tests/test_toolviewtoolbar.cpp:72:22
    #4 0x2beefe in TestToolViewToolBar::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/arr/projects/kdevelop/build/kdevplatform/sublime/tests/test_toolviewtoolbar_autogen/EWIEGA46WW/moc_test_toolviewtoolbar.cpp:84:21
    #5 0x8020320ce in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (/usr/local/lib/qt5/libQt5Core.so.5+0x4320ce)
    #6 0x80032302d  (/usr/local/lib/qt5/libQt5Test.so.5+0x1e02d)
    #7 0x800323bee  (/usr/local/lib/qt5/libQt5Test.so.5+0x1ebee)
    #8 0x800324988  (/usr/local/lib/qt5/libQt5Test.so.5+0x1f988)
    #9 0x80032517b in QTest::qRun() (/usr/local/lib/qt5/libQt5Test.so.5+0x2017b)
    #10 0x800324ef3 in QTest::qExec(QObject*, int, char**) (/usr/local/lib/qt5/libQt5Test.so.5+0x1fef3)
    #11 0x2b97fb in main /home/arr/projects/kdevelop/kdevplatform/sublime/tests/test_toolviewtoolbar.cpp:144:1

SUMMARY: AddressSanitizer: heap-use-after-free /usr/local/include/qt5/QtCore/qscopedpointer.h:118:16 in QScopedPointer<Sublime::ViewPrivate, QScopedPointerDeleter<Sublime::ViewPrivate> >::operator->() const
==21936==ABORTING
```

Subscribers: kdevelop-devel, #kdevelop

Tags: #kdevelop

Differential Revision: https://phabricator.kde.org/D18463
parent 9ed5d45b
......@@ -80,7 +80,9 @@ public:
private:
bool eventFilter(QObject * watched, QEvent * event) override
{
if (watched == m_dock->view()->widget() && event->type() == QEvent::EnabledChange) {
// an event may arrive when m_dock->view()->widget() is already destroyed
// so check for event type first.
if (event->type() == QEvent::EnabledChange && watched == m_dock->view()->widget()) {
refreshText();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment