-
Bug
-
Resolution: Done
-
Not Evaluated
-
Qt Creator 4.9.2
-
None
-
-
a6d3101207901172ddab3593dbd500d89d799128
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
| For Gerrit Dashboard: QTCREATORBUG-22637 | ||||||
|---|---|---|---|---|---|---|
| # | Subject | Branch | Project | Status | CR | V |
| 267251,3 | Debugger: Avoid infinite loop in dumper | 4.10 | qt-creator/qt-creator | Status: MERGED | +2 | 0 |