Details
-
Bug
-
Resolution: Done
-
Not Evaluated
-
Qt Creator 4.9.2
-
None
-
-
a6d3101207901172ddab3593dbd500d89d799128
Description
Qt Creator hangs when I have debugging helpers enabled and I reach code containing a local variable with a rather complex type (template instantiation of a boost::multi_index_container).
When this happens I need to kill gdb to get back control over Qt Creator.
I did some digging and could track (part of) the problem to the code that strips the template parameters from the typename in the method 'stripNamespaceFromType()' in share/qtcreator/debugger/dumper.py (around line 1223). It appears that, for some reason, the typename passed in is truncated and the <> pairs that are searched for and stripped are no longer balanced. In my particular case, I see the following chopped off typename upon entering the method:
------------------ STRIPPING typename: (len 2075): boost::multi_index::detail::header_holder<std::allocator_traits<boost::detail::allocator::compliant_allocator_rebind_to<std::allocator<CDiaLoadCase *>, boost::multi_index::detail::multi_index_node_type<CDiaLoadCase *, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<mc::name, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na>, mc::NameKeyExtractor<CDiaLoadCase>, mc::qHashAdapter<QString>, boost::mpl::na>, boost::multi_index::hashed_unique<boost::multi_index::tag<mc::userid, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na>, mc::UserIdKeyExtractor<CDiaLoadCase>, UserIdHash, boost::mpl::na>, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na>, std::allocator<CDiaLoadCase *> >::type>::type>::pointer, boost::multi_index::multi_index_container<CDiaLoadCase *, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<mc::name, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na, boost::mpl::na>, mc::NameKeyExtractor<CDiaLoadCase>, mc::qHashAdapter<QString>, boost::mpl::na>, boost::multi_index::hashed_unique<boost::mu
This is the code of the relevant method in dumper.py:
def stripNamespaceFromType(self, typeName): ns = self.qtNamespace() if len(ns) > 0 and typeName.startswith(ns): typeName = typeName[len(ns):] pos = typeName.find('<') # FIXME: make it recognize foo<A>::bar<B>::iterator? while pos != -1: pos1 = typeName.rfind('>', pos) typeName = typeName[0:pos] + typeName[pos1+1:] pos = typeName.find('<') return typeName
In the case above, after the first run though the loop the unterminated '<' at the end is found, causing the loop to continue and pos1 to become -1 as there is no terminating '>' after pos. The whole typeName is then appended again (as pos1+1 is 0, typeName[0:] is appended).
I did not investigate why the typename that is passed in is truncated (which could be considered the root cause).
In the mean time, I have patched the routine as below to make it more robust against unbalanced template argument braces ('<>').
def stripNamespaceFromType(self, typeName): ns = self.qtNamespace() if len(ns) > 0 and typeName.startswith(ns): typeName = typeName[len(ns):] # warn( 'stripping %s' % typeName ) lvl = 0 pos = None stripChunks = [] sz = len(typeName) for index in range(0, sz): s = typeName[index] if s == '<': lvl += 1 if lvl == 1: pos = index continue elif s == '>': lvl -= 1 if lvl < 0 : error( "unbalanced! @index %d" % index ) if lvl == 0: stripChunks.append( (pos, index+1) ) if lvl != 0: error( "unbalanced at end of expression" ) for (f,l) in reversed( stripChunks ): typeName = typeName[:f] + typeName[l:] return typeName