Uploaded image for project: 'Qt Creator'
  1. Qt Creator
  2. QTCREATORBUG-22637

Debug helper: infinite loop

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Not Evaluated
    • Resolution: Done
    • Affects Version/s: Qt Creator 4.9.2
    • Fix Version/s: Qt Creator 4.10.1
    • Component/s: Debugger
    • Labels:
      None

      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
      
      

       

       

        Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            Assignee:
            hjk hjk
            Reporter:
            xburgerhout Xander
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes