yvesdm3000 / ClangLib

Code::Blocks plugin integrating various features of LLVM Clang.
5 stars 4 forks source link

bad_alloc exception (memory overflow?) #13

Open bluehazzard opened 7 years ago

bluehazzard commented 7 years ago

I work on the codeblock code (so quite large project) on Windows and after some time i get a crash with this back trace:

#0 0x9ec4350    __cxa_throw() ([...]\output\share\CodeBlocks\plugins\clanglib.dll:??)
#1 0x9ec41c6    operator new(unsigned int) () ([...]\output\share\CodeBlocks\plugins\clanglib.dll:??)
#2 0x9fa0f58    typeinfo for std::time_put<wchar_t, std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >() ([...]\output\share\CodeBlocks\plugins\clanglib.dll:??)
#3 0x9ec82c0    std::bad_alloc::what() const() ([...]\output\share\CodeBlocks\plugins\clanglib.dll:??)
#4 0x9f5801d    std::allocator_traits<std::allocator<ClAbstractToken> >::max_size(__a=...) ([tdm_gcc_4.9]include/c++/bits/alloc_traits.h:422)
#5 0x9f57ffc    std::allocator_traits<std::allocator<ClAbstractToken> >::allocate(__a=..., __n=262144) ([tdm_gcc_4.9]include/c++/bits/alloc_traits.h:357)
#6 0x9f41a2d    std::_Vector_base<ClAbstractToken, std::allocator<ClAbstractToken> >::_M_allocate(this=0x75119fdc, __n=262144) ([tdm_gcc_4.9]include/c++/bits/stl_vector.h:170)
#7 0x9f67dc6    std::vector<ClAbstractToken, std::allocator<ClAbstractToken> >::_M_emplace_back_aux<ClAbstractToken const&>(this=0x75119fdc) ([tdm_gcc_4.9]include/c++/bits/vector.tcc:412)
#8 0x9f6816e    std::vector<ClAbstractToken, std::allocator<ClAbstractToken> >::push_back(this=0x75119fdc, __x=...) ([tdm_gcc_4.9]include/c++/bits/stl_vector.h:923)
#9 0x9eff36c    ClTreeMap<ClAbstractToken>::Insert(this=0x75119fd8, key="_M_get_Tp_allocator", value=...) ([...]ClangLib/src/treemap.h:38)
#10 0x9ebaf3a   ClTokenDatabase::InsertToken(this=0xa8cfdcc, token=...) ([...]ClangLib\src\tokendatabase.cpp:1070)
#11 0x9ec1b05   ClImportClangToken(cursor=..., scopeCursor=..., typ=ClTokenType_FuncRef, client_data=0xa8cfcc8) ([...]ClangLib\src\translationunit.cpp:997)
#12 0x9ec1ff5   ClAST_Visitor(cursor=..., parent=..., client_data=0xa8cfcc8) ([...]ClangLib\src\translationunit.cpp:1101)
#13 0xf9abd11   libclang!clang_isTranslationUnit() ([...]\output\libclang.dll:??)
#14 0x66    ?? () (??:??)
#15 ??  ?? () (??:??)

The ram usage of codeblocks at this moment is 1.079GByte (normally it is somewhere about 300MB)

in src/treemap.h:32

template<typename _TpVal>
class ClTreeMap
{
public:
    // returns the id of the value inserted
    int Insert(const std::string& key, const _TpVal& value)
    {
        m_Data.push_back(value);
        return m_Tree.Insert(key, m_Data.size() - 1);
    }

the size reported from m_Data.size() is 131072

i have no idea how to debug this error. I have also no idea if this is a memory leak or that the codebase is simply to large (but i don't think that this is the problem, because clang does not throw a badalloc )....

any hint would be appreciated

yvesdm3000 commented 7 years ago

Hi,

It's a known problem that the treemap keeps filling up. Deleted entries have its value mostly deleted, but the entry in the vector&map is not removed. This is because of an initial design decision from the original "Alpha" code where each symbol gets an entry in a vector and then keyed in a map. Removing entries in the vector would change all id's that follows the deleted id. I tried to replace it with something more flexible, but then new features popped up that the "new" design didn't cover, so I went along for now with this original design. However I don't think this is the source of the memory leak. It's just an entry in the vector+map that floats around with hardly any data in it and is cleared when the app is restarted.

Maybe some memory-leak tracing tool like valgrind or DrMemory might help ?

Yves

bluehazzard commented 7 years ago

i tried DrMemory, but it crashed, because of internal out of memory xD

I noticed that this crash only happens if my code does not compile. If the code compiles all seems to be ok. Can it be that the plugin does not detect that the parser returned with an error and continued to launch parsers at infinitum?

yvesdm3000 commented 7 years ago

I don't think "launching" parsers can be a problem unless maybe they are continuously queued. There are only a couple of threads: The UI thread obviously which also serves as the controlling thread. Then there is a thread to perform code completion and most other operations and a thread with the single purpose to do the background indexing (which might become a threadpool in the future). Since a month or so I introduced another thread that is only used for parsing so that parsing is decoupled from code-completion using 2 instances of a translation-unit. This way the user still has code-completion while a file is re-parsed. If the crash happens when the code doesn't compile, I would rather look at the warning&errors subsystem. I use this plugin on a codebase of a couple of gigabytes worth of sources so the size of the project is probably also not an issue. I do notice memory usage can be pretty large on large files and&or big include trees.