https://bugs.kde.org/show_bug.cgi?id=445699

Milian Wolff <m...@milianw.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED
      Latest Commit|                            |https://invent.kde.org/kdev
                   |                            |elop/kdevelop/commit/387131
                   |                            |2163689fd985832726eea7f0d86
                   |                            |663d931

--- Comment #2 from Milian Wolff <m...@milianw.de> ---
Git commit 3871312163689fd985832726eea7f0d86663d931 by Milian Wolff, on behalf
of Igor Kushnir.
Committed on 26/11/2021 at 08:11.
Pushed by igorkushnir into branch 'master'.

DocumentParsePlan: don't cache often-invalidated cend()

The loop in DocumentParsePlan::removeTargetsForListener() caches
m_targets.cend(), which can become invalidated when a target is erased
inside this loop. Comparing to the invalidated end iterator leads to
undefined behavior.

This undefined behavior makes QmlJS's test_files crash every other time,
both on my system and on the CI. The alternating crashes of this test
can be seen by clicking Next Build repeatedly starting from the first
build since the bug was introduced:
https://build.kde.org/job/KDevelop/job/kdevelop/job/kf5-qt5%20SUSEQt5.15/165/testReport/junit/projectroot.plugins.qmljs/tests/test_files/

KDevelop often crashes because of this undefined behavior too (see the
bug report referenced below).

m_targets is a QSet, which is implemented in terms of QHash. QHash's end
iterator `e` equals the d-pointer `d` via anonymous union. So the only
way cend() can be invalidated is if QSet::erase() detaches. That's
possible, because an entire DocumentParsePlan is copied in
BackgroundParserPrivate::parseDocumentsInternal():
    const DocumentParsePlan parsePlan = *parsePlanConstIt;
The involvement of multithreading explains why test_files crashes every
other time rather than each time. Examining call stacks of both
test_files and kdevelop crashes confirms this hypothesis: a background
thread crashes in DocumentParsePlan::removeTargetsForListener() while
the main thread waits on the `m_mutex.lock()` line in
parseDocumentsInternal().

This bug was introduced in 5ee9b9fe9740f2820f3ee1a575fcda2cbe142e4f.

M  +1    -1    kdevplatform/language/backgroundparser/backgroundparser.cpp

https://invent.kde.org/kdevelop/kdevelop/commit/3871312163689fd985832726eea7f0d86663d931

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to