Skip to content

Commit

Permalink
Don't crash when attaching to QiTissue
Browse files Browse the repository at this point in the history
This patch fixes runtime attaching to an ASAN-enabled QiTissue.
Previously I got the following crash reliably at startup:

```
==352112==ERROR: AddressSanitizer: SEGV on unknown address 0x604016000459 (pc 0x7feb421bed63 bp 0x7ffdaed25490 sp 0x7ffdaed25478 T0)
==352112==The signal is caused by a READ memory access.
    #0 0x7feb421bed62 in QHashData::nextNode(QHashData::Node*) (/usr/lib/libQt5Core.so.5+0x104d62)
    #1 0x7fea9efc9932 in QHash<GammaRay::ToolFactory*, QHashDummyValue>::iterator::operator++() /usr/include/qt/QtCore/qhash.h:345
    #2 0x7fea9efc8663 in QSet<GammaRay::ToolFactory*>::iterator::operator++() /usr/include/qt/QtCore/qset.h:129
    #3 0x7fea9efc6e0c in GammaRay::ToolManager::objectAdded(QMetaObject const*) ../core/toolmanager.cpp:217
    #4 0x7fea9efc6b67 in GammaRay::ToolManager::objectAdded(QObject*) ../core/toolmanager.cpp:194
    #5 0x7fea9efa7b22 in GammaRay::Probe::objectFullyConstructed(QObject*) ../core/probe.cpp:688
    #6 0x7fea9efa76b0 in GammaRay::Probe::objectAdded(QObject*, bool) ../core/probe.cpp:612
    #7 0x7fea9efa8a30 in GammaRay::Probe::discoverObject(QObject*) ../core/probe.cpp:907
    #8 0x7fea9efa8876 in GammaRay::Probe::findExistingObjects() ../core/probe.cpp:889
    #9 0x7fea9efa6097 in GammaRay::Probe::createProbe(bool) ../core/probe.cpp:351
    #10 0x7fead53fb5e7 in GammaRay::ProbeCreator::createProbe() ../probe/probecreator.cpp:92
    #11 0x7fead53fae5f in GammaRay::ProbeCreator::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) probe/gammaray_probe_obj_autogen/EWIEGA46WW/moc_probecreator.cpp:72
    #12 0x7feb4238cad9 in QObject::event(QEvent*) (/usr/lib/libQt5Core.so.5+0x2d2ad9)
    #13 0x7feb43294351 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/libQt5Widgets.so.5+0x15b351)
    #14 0x7feb4329d828 in QApplication::notify(QObject*, QEvent*) (/usr/lib/libQt5Widgets.so.5+0x164828)
    #15 0x7feb4235f4f1 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/libQt5Core.so.5+0x2a54f1)
    #16 0x7feb42361d55 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (/usr/lib/libQt5Core.so.5+0x2a7d55)
    #17 0x7feb423b8243  (/usr/lib/libQt5Core.so.5+0x2fe243)
    #18 0x7feb206da6bd in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6b6bd)
    #19 0x7feb206dc530  (/usr/lib/libglib-2.0.so.0+0x6d530)
    #20 0x7feb206dc570 in g_main_context_iteration (/usr/lib/libglib-2.0.so.0+0x6d570)
    #21 0x7feb423b788f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/libQt5Core.so.5+0x2fd88f)
    #22 0x7feb4235e05b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/libQt5Core.so.5+0x2a405b)
    #23 0x7feb42366065 in QCoreApplication::exec() (/usr/lib/libQt5Core.so.5+0x2ac065)
    #24 0x5643dbe05406 in main ../KDAB/qitissue/main.cpp:258
    #25 0x7feb41269022 in __libc_start_main (/usr/lib/libc.so.6+0x27022)
    #26 0x5643dbdfd1ed in _start (/home/milian/projects/kdab/qitissue/build-asan/bin/QiTissue+0x6b1ed)
```

I can only explain this by assuming that the list got mutated while
iterating over it, i.e. basically a recursion of `objectAdded` which
could happen when we init the factory?
  • Loading branch information
milianw committed Sep 21, 2021
1 parent 7de2e0c commit c95a4f5
Showing 1 changed file with 4 additions and 6 deletions.
10 changes: 4 additions & 6 deletions core/toolmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,14 @@ void ToolManager::objectAdded(const QMetaObject *mo)
if (mo->superClass())
objectAdded(mo->superClass());

for (auto it = m_disabledTools.begin(); it != m_disabledTools.end();) {
ToolFactory *factory = *it;
// operate on copy to ensure potential recursion isn't invalidating the iterators
const auto disabledToolsCopy = m_disabledTools;
for (auto *factory : disabledToolsCopy) {
const auto begin = factory->supportedTypes().constBegin();
const auto end = factory->supportedTypes().constEnd();
if (std::find(begin, end, mo->className()) != end) {
it = m_disabledTools.erase(it);
if (std::find(begin, end, mo->className()) != end && m_disabledTools.remove(factory)) {
factory->init(Probe::instance());
emit toolEnabled(factory->id());
} else {
++it;
}
}
}
Expand Down

0 comments on commit c95a4f5

Please sign in to comment.