Commit a8ffba2c authored by Milian Wolff's avatar Milian Wolff
Browse files

Don't crash on exit when clearing PersistentSymbolTable caches

Instead clear the cache early when the PersistentSymbolTable is
destroyed, not only once we destroy the repository. At the latter
stage, the items referenced by the cache might be gone already,
leading to crashes such as:

```
=================================================================
==25768==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b000089bb4 at pc 0x7effefaf1018 bp 0x7ffea79d94c0 sp 0x7ffea79d94b8
READ of size 4 at 0x60b000089bb4 thread T0
    #0 0x7effefaf1017 in QVector<KDevelop::Bucket<Utils::SetNodeData, Utils::SetNodeDataRequest, false, 24u>*>::size() const /usr/include/qt5/QtCore/qvector.h:88
    #1 0x7effefaf1d45 in KDevelop::ItemRepository<Utils::SetNodeData, Utils::SetNodeDataRequest, false, QRecursiveMutex, 24u, 1048576u>::verifyIndex(unsigned int) const /builds/kdevelop/kdevelop/kdevplatform/serialization/itemrepository.h:2252
    #2 0x7efff0157ad7 in KDevelop::ItemRepository<Utils::SetNodeData, Utils::SetNodeDataRequest, false, QRecursiveMutex, 24u, 1048576u>::dynamicItemFromIndexSimple(unsigned int) /builds/kdevelop/kdevelop/kdevplatform/serialization/itemrepository.h:1533
    #3 0x7efff014e331 in Utils::Set::unrefNode(unsigned int) /builds/kdevelop/kdevelop/kdevplatform/language/util/setrepository.cpp:1143
    #4 0x7efff014e7d2 in Utils::Set::staticUnref() /builds/kdevelop/kdevelop/kdevplatform/language/util/setrepository.cpp:1173
    #5 0x7effeff064c7 in ~StorableSet /builds/kdevelop/kdevelop/kdevplatform/language/util/setrepository.h:187
    #6 0x7effeff1e8d5 in ~QHashNode /usr/include/qt5/QtCore/qhash.h:147
    #7 0x7effeff1e951 in deleteNode2 /usr/include/qt5/QtCore/qhash.h:595
    #8 0x7effde12975b in QHashData::free_helper(void (*)(QHashData::Node*)) (/lib64/libQt5Core.so.5+0x13175b)
    #9 0x7effeff0b679 in freeData /usr/include/qt5/QtCore/qhash.h:619
    #10 0x7effeff014e7 in ~QHash /usr/include/qt5/QtCore/qhash.h:250
    #11 0x7effeff28264 in ~PersistentSymbolTableRepo /builds/kdevelop/kdevelop/kdevplatform/language/duchain/persistentsymboltable.cpp:192
    #12 0x7effddaef104 in __run_exit_handlers (/lib64/libc.so.6+0x59104)
    #13 0x7effddaef28f in exit (/lib64/libc.so.6+0x5928f)
    #14 0x7effddad65b6 in __libc_start_call_main (/lib64/libc.so.6+0x405b6)
    #15 0x7effddad6678 in __libc_start_main_alias_1 (/lib64/libc.so.6+0x40678)
    #16 0x407ed4 in _start (/builds/kdevelop/kdevelop/_build/bin/test_files+0x407ed4)

0x60b000089bb4 is located 4 bytes inside of 104-byte region [0x60b000089bb0,0x60b000089c18)
freed by thread T0 here:
    #0 0x7efff53080c8  (/lib64/libasan.so.8+0xbb0c8)
    #1 0x7effefb07210 in QTypedArrayData<KDevelop::Bucket<Utils::SetNodeData, Utils::SetNodeDataRequest, false, 24u>*>::deallocate(QArrayData*) /usr/include/qt5/QtCore/qarraydata.h:240
    #2 0x7effefafe448 in QVector<KDevelop::Bucket<Utils::SetNodeData, Utils::SetNodeDataRequest, false, 24u>*>::freeData(QTypedArrayData<KDevelop::Bucket<Utils::SetNodeData, Utils::SetNodeDataRequest, false, 24u>*>*) /usr/include/qt5/QtCore/qvector.h:579
    #3 0x7efff0158e5f in QVector<KDevelop::Bucket<Utils::SetNodeData, Utils::SetNodeDataRequest, false, 24u>*>::~QVector() /usr/include/qt5/QtCore/qvector.h:73
    #4 0x7efff0151888 in KDevelop::ItemRepository<Utils::SetNodeData, Utils::SetNodeDataRequest, false, QRecursiveMutex, 24u, 1048576u>::~ItemRepository() /builds/kdevelop/kdevelop/kdevplatform/serialization/itemrepository.h:1128
    #5 0x7efff01673f6 in Utils::SetDataRepository::~SetDataRepository() /builds/kdevelop/kdevelop/kdevplatform/language/util/basicsetrepository.h:178
    #6 0x7efff014b9f4 in Utils::BasicSetRepository::~BasicSetRepository() /builds/kdevelop/kdevelop/kdevplatform/language/util/setrepository.cpp:987
    #7 0x7effddaef104 in __run_exit_handlers (/lib64/libc.so.6+0x59104)
```
parent 38295d73
Pipeline #205578 passed with stage
in 26 minutes and 9 seconds
......@@ -231,7 +231,11 @@ PersistentSymbolTable::PersistentSymbolTable()
RecursiveImportCacheRepository::repository();
}
PersistentSymbolTable::~PersistentSymbolTable() = default;
PersistentSymbolTable::~PersistentSymbolTable()
{
// clear cache early to ensure we don't keep items referenced from other repositories
clearCache();
  • PersistentSymbolTableRepo is destroyed almost immediately after PersistentSymbolTable because its construction finishes almost immediately before. I think the only intervening constructed/destroyed object is RecursiveImportCacheRepository::repository(). So reordering the construction of these two objects in PersistentSymbolTable() is probably a better fix. After all PersistentSymbolTableRepo depends on RecursiveImportCacheRepository::repository() but not vice versa.

  • Created !371 (merged) with the alternative fix.

Please register or sign in to reply
}
void PersistentSymbolTable::addDeclaration(const IndexedQualifiedIdentifier& id, const IndexedDeclaration& declaration)
{
......
Supports Markdown
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