Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • KDevelop KDevelop
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 9
    • Issues 9
    • List
    • Boards
    • Service Desk
    • Milestones
  • Bugzilla
    • Bugzilla
  • Merge requests 54
    • Merge requests 54
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • KDevelopKDevelop
  • KDevelopKDevelop
  • Merge requests
  • !380

Use a recursive mutex for the PersistentSymbolTable

  • Review changes

  • Download
  • Email patches
  • Plain diff
Merged Milian Wolff requested to merge work/recursive-persistentsymboltable-locking into master Oct 03, 2022
  • Overview 37
  • Commits 3
  • Pipelines 10
  • Changes 2

The visitDeclarations and visitFilteredDeclarations might be nested, which means we have to account for potentially recursive mutex locking. The kdev-php plugin exhibits this behavior when it calls KDevelop::DUContext::findDeclarations, which might lead to recursive visitFilteredDeclarations within the KDevelop::TopDUContext::applyAliases method. I.e. the deadlock in the uses unit test suite of kdev-php occurred within:

(gdb) bt
#0  0x00007ffff2b1959d in syscall () at /usr/lib/libc.so.6
#1  0x00007ffff30dfb06 in QBasicMutex::lockInternal() () at /usr/lib/libQt5Core.so.5
#2  0x00007ffff5c95d87 in QMutexLocker::QMutexLocker(QBasicMutex*) (this=0x7fffffff7808, m=0x7ffff75ede50 <KDevelop::ItemRepositoryFor<KDevelop::PersistentSymbolTable>::repo()::mutex>)
    at /usr/include/qt/QtCore/qmutex.h:238
#3  0x00007ffff5dc0d0e in KDevelop::LockedItemRepository::write<KDevelop::PersistentSymbolTable, KDevelop::PersistentSymbolTable::visitFilteredDeclarations(const KDevelop::IndexedQualifiedIdentifier&, const KDevelop::TopDUContext::IndexedRecursiveImports&, const DeclarationVisitor&) const::<lambda(KDevelop::(anonymous namespace)::PersistentSymbolTableRepo&)> >(struct {...} &&) (op=...) at /home/milian/projects/kde/src/kdevelop/kdevplatform/serialization/itemrepository.h:2310
#4  0x00007ffff5dc0df8 in KDevelop::PersistentSymbolTable::visitFilteredDeclarations(KDevelop::IndexedQualifiedIdentifier const&, Utils::StorableSet<KDevelop::IndexedTopDUContext, KDevelop::IndexedTopDUContextIndexConversion, KDevelop::RecursiveImportRepository, true, Utils::DummyLocker> const&, std::function<KDevelop::PersistentSymbolTable::VisitorState (KDevelop::IndexedDeclaration const&)> const&) const (this=0x7ffff77ec5c8 <KDevelop::PersistentSymbolTable::self()::ret>, id=..., visibility=..., visitor=...)
    at /home/milian/projects/kde/src/kdevelop/kdevplatform/language/duchain/persistentsymboltable.cpp:361
#5  0x00007ffff5d2eb11 in KDevelop::TopDUContext::FindDeclarationsAcceptor::operator()(KDevelop::QualifiedIdentifier const&) (this=0x7fffffff8ff0, id=...)
    at /home/milian/projects/kde/src/kdevelop/kdevplatform/language/duchain/topducontext.cpp:688
#6  0x00007ffff5d3542c in KDevelop::TopDUContext::applyAliases<KDevelop::TopDUContext::FindDeclarationsAcceptor>(KDevelop::QualifiedIdentifier const&, QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem> const&, KDevelop::TopDUContext::FindDeclarationsAcceptor&, KDevelop::CursorInRevision const&, bool, KDevelop::TopDUContext::ApplyAliasesBuddyInfo*, unsigned int) const (this=0x555555b80260, previous=..., identifier=..., accept=..., position=..., canBeNamespace=false, buddy=0x7fffffff7b00, recursionDepth=1)
    at /home/milian/projects/kde/src/kdevelop/kdevplatform/language/duchain/topducontext.cpp:857
#7  0x00007ffff5d34aed in KDevelop::TopDUContext::applyAliases<KDevelop::TopDUContext::FindDeclarationsAcceptor>(KDevelop::QualifiedIdentifier const&, QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem> const&, KDevelop::TopDUContext::FindDeclarationsAcceptor&, KDevelop::CursorInRevision const&, bool, KDevelop::TopDUContext::ApplyAliasesBuddyInfo*, unsigned int) const::{lambda(KDevelop::IndexedDeclaration const&)#1}::operator()(KDevelop::IndexedDeclaration const&) const (__closure=0x555555a86fe0, indexedAliasDecl=...)
    at /home/milian/projects/kde/src/kdevelop/kdevplatform/language/duchain/topducontext.cpp:839
#8  0x00007ffff5d3becf in std::__invoke_impl<KDevelop::PersistentSymbolTable::VisitorState, KDevelop::TopDUContext::applyAliases<KDevelop::TopDUContext::FindDeclarationsAcceptor>(KDevelop::QualifiedIdentifier const&, QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem> const&, KDevelop::TopDUContext::FindDeclarationsAcceptor&, KDevelop::CursorInRevision const&, bool, KDevelop::TopDUContext::ApplyAliasesBuddyInfo*, unsigned int) const::{lambda(KDevelop::IndexedDeclaration const&)#1}&, KDevelop::IndexedDeclaration const&>(std::__invoke_other, KDevelop::TopDUContext::applyAliases<KDevelop::TopDUContext::FindDeclarationsAcceptor>(KDevelop::QualifiedIdentifier const&, QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem> const&, KDevelop::TopDUContext::FindDeclarationsAcceptor&, KDevelop::CursorInRevision const&, bool, KDevelop::TopDUContext::ApplyAliasesBuddyInfo*, unsigned int) const::{lambda(KDevelop::IndexedDeclaration const&)#1}&, KDevelop::IndexedDeclaration const&) (__f=...) at /usr/include/c++/12.2.0/bits/invoke.h:61
#9  0x00007ffff5d3b932 in std::__invoke_r<KDevelop::PersistentSymbolTable::VisitorState, KDevelop::TopDUContext::applyAliases<KDevelop::TopDUContext::FindDeclarationsAcceptor>(KDevelop::QualifiedIdentifier const&, QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem> const&, KDevelop::TopDUContext::FindDeclarationsAcceptor&, KDevelop::CursorInRevision const&, bool, KDevelop::TopDUContext::ApplyAliasesBuddyInfo*, unsigned int) const::{lambda(KDevelop::IndexedDeclaration const&)#1}&, KDevelop::IndexedDeclaration const&>(KDevelop::TopDUContext::applyAliases<KDevelop::TopDUContext::FindDeclarationsAcceptor>(KDevelop::QualifiedIdentifier const&, QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem> const&, KDevelop::TopDUContext::FindDeclarationsAcceptor&, KDevelop::CursorInRevision const&, bool, KDevelop::TopDUContext::ApplyAliasesBuddyInfo*, unsigned int) const::{lambda(KDevelop::IndexedDeclaration const&)#1}&, KDevelop::IndexedDeclaration const&) (__fn=...) at /usr/include/c++/12.2.0/bits/invoke.h:114
#10 0x00007ffff5d3adbe in std::_Function_handler<KDevelop::PersistentSymbolTable::VisitorState (KDevelop::IndexedDeclaration const&), KDevelop::TopDUContext::applyAliases<KDevelop::TopDUContext::FindDeclarationsAcceptor>(KDevelop::QualifiedIdentifier const&, QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem> const&, KDevelop::TopDUContext::FindDeclarationsAcceptor&, KDevelop::CursorInRevision const&, bool, KDevelop::TopDUContext::ApplyAliasesBuddyInfo*, unsigned int) const::{lambda(KDevelop::IndexedDeclaration const&)#1}>::_M_invoke(std::_Any_data const&, KDevelop::IndexedDeclaration const&) (__functor=..., __args#0=...) at /usr/include/c++/12.2.0/bits/std_function.h:290
#11 0x00007ffff5dcf371 in std::function<KDevelop::PersistentSymbolTable::VisitorState (KDevelop::IndexedDeclaration const&)>::operator()(KDevelop::IndexedDeclaration const&) const
    (this=0x7fffffff8ed0, __args#0=...) at /usr/include/c++/12.2.0/bits/std_function.h:591
#12 0x00007ffff5dc0c5d in operator()(KDevelop::(anonymous namespace)::PersistentSymbolTableRepo&) const (__closure=0x7fffffff8d70, repo=...)
#13 0x00007ffff5dc0d21 in KDevelop::LockedItemRepository::write<KDevelop::PersistentSymbolTable, KDevelop::PersistentSymbolTable::visitFilteredDeclarations(const KDevelop::IndexedQualifiedIdentifier&, const KDevelop::TopDUContext::IndexedRecursiveImports&, const DeclarationVisitor&) const::<lambda(KDevelop::(anonymous namespace)::PersistentSymbolTableRepo&)> >(struct {...} &&) (op=...) at /home/milian/projects/kde/src/kdevelop/kdevplatform/serialization/itemrepository.h:2311
#14 0x00007ffff5dc0df8 in KDevelop::PersistentSymbolTable::visitFilteredDeclarations(KDevelop::IndexedQualifiedIdentifier const&, Utils::StorableSet<KDevelop::IndexedTopDUContext, KDevelop::IndexedTopDUContextIndexConversion, KDevelop::RecursiveImportRepository, true, Utils::DummyLocker> const&, std::function<KDevelop::PersistentSymbolTable::VisitorState (KDevelop::IndexedDeclaration const&)> const&) const (this=0x7ffff77ec5c8 <KDevelop::PersistentSymbolTable::self()::ret>, id=..., visibility=..., visitor=...)
    at /home/milian/projects/kde/src/kdevelop/kdevplatform/language/duchain/persistentsymboltable.cpp:361
#15 0x00007ffff5d35372 in KDevelop::TopDUContext::applyAliases<KDevelop::TopDUContext::FindDeclarationsAcceptor>(KDevelop::QualifiedIdentifier const&, QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem> const&, KDevelop::TopDUContext::FindDeclarationsAcceptor&, KDevelop::CursorInRevision const&, bool, KDevelop::TopDUContext::ApplyAliasesBuddyInfo*, unsigned int) const (this=0x555555b80260, previous=..., identifier=..., accept=..., position=..., canBeNamespace=false, buddy=0x0, recursionDepth=0)
    at /home/milian/projects/kde/src/kdevelop/kdevplatform/language/duchain/topducontext.cpp:795
#16 0x00007ffff5d30e98 in KDevelop::TopDUContext::applyAliases<KDevelop::TopDUContext::FindDeclarationsAcceptor>(KDevVarLengthArray<QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem>, 256> const&, KDevelop::TopDUContext::FindDeclarationsAcceptor&, KDevelop::CursorInRevision const&, bool) const
    (this=0x555555b80260, identifiers=..., acceptor=..., position=..., canBeNamespace=false) at /home/milian/projects/kde/src/kdevelop/kdevplatform/language/duchain/topducontext.cpp:942
#17 0x00007ffff5d2b2fe in KDevelop::TopDUContext::findDeclarationsInternal(KDevVarLengthArray<QExplicitlySharedDataPointer<KDevelop::DUContext::SearchItem>, 256> const&, KDevelop::CursorInRevision const&, KDevelop::TypePtr<KDevelop::AbstractType> const&, QList<KDevelop::Declaration*>&, KDevelop::TopDUContext const*, QFlags<KDevelop::DUContext::SearchFlag>, unsigned int) const (this=0x555555b80260, identifiers=..., position=..., dataType=..., ret=QList<KDevelop::Declaration *> (size = 0), flags=...)
    at /home/milian/projects/kde/src/kdevelop/kdevplatform/language/duchain/topducontext.cpp:724
#18 0x00007ffff5d00345 in KDevelop::DUContext::findDeclarations(KDevelop::QualifiedIdentifier const&, KDevelop::CursorInRevision const&, KDevelop::TypePtr<KDevelop::AbstractType> const&, KDevelop::TopDUContext const*, QFlags<KDevelop::DUContext::SearchFlag>) const (this=0x555555b80260, identifier=..., position=..., dataType=..., topContext=0x0, flags=...)
    at /home/milian/projects/kde/src/kdevelop/kdevplatform/language/duchain/ducontext.cpp:793
...

This patch here fixes that deadlock.

@wiesinger

Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: work/recursive-persistentsymboltable-locking