Bug 335914

Summary: crash on importing qt 4 source
Product: [Applications] umbrello Reporter: Ralf Habacker <ralf.habacker>
Component: generalAssignee: Oliver Kellogg <okellogg>
Status: RESOLVED FIXED    
Severity: crash CC: okellogg
Priority: NOR    
Version: 2.13.1   
Target Milestone: ---   
Platform: unspecified   
OS: All   
Latest Commit: Version Fixed In: 4.13.3
Sentry Crash Report:

Description Ralf Habacker 2014-06-07 09:03:42 UTC
umbrello crashes on importing qt source 4.8.6


Reproducible: Always

Steps to Reproduce:
1. open umbrello 
2. run code->import project and select qt source root dir
Actual Results:  
umbrello crashes

Expected Results:  
umbrello should not crash

#0  0x00007ffff3bf7d8d in vfprintf () from /lib64/libc.so.6
#1  0x00007ffff3bfcff1 in buffered_vfprintf () from /lib64/libc.so.6
#2  0x00007ffff3bf7ebe in vfprintf () from /lib64/libc.so.6
#3  0x00007ffff3ca721e in __fprintf_chk () from /lib64/libc.so.6
#4  0x00007ffff56dc4e1 in fprintf (__fmt=0x7ffff584a062 "%s\n", __stream=<optimized out>) at /usr/include/bits/stdio2.h:98
#5  qt_message_output (msgType=QtCriticalMsg, buf=<optimized out>) at global/qglobal.cpp:2325
#6  0x000000000044d30b in QDebug::~QDebug (this=0x7fffff801da0, __in_chrg=<optimized out>) at /usr/include/QtCore/qdebug.h:85
#7  0x00000000004f4baa in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:96
#8  0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#9  0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#10 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#11 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#12 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#13 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#14 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#15 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#16 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#17 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#18 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#19 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#20 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#21 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#22 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#23 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#24 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#25 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#26 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#27 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#28 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#29 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#30 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#31 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#32 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#33 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#34 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#35 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#36 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#37 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#38 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#39 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#40 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91
#41 0x00000000004f4b23 in CppImport::feedTheModel (this=this@entry=0xe0efd0, fileName=...) at /home/ralf/src/umbrello-4.13/umbrello/codeimport/cppimport.cpp:91

The crash happens on importing /usr/src/debug/qt-everywhere-opensource-src-4.8.6/src/3rdparty/clucene/src/CLucene/queryParser/MultiFieldQueryParser.h
Comment 1 Ralf Habacker 2014-06-07 09:08:12 UTC
A workaround I found is adding the line indicated with '+'.

void CppImport::feedTheModel(const QString& fileName)
{
    if (ms_seenFiles.indexOf(fileName) != -1)
        return;
    QMap<QString, Dependence> deps = ms_driver->dependences(fileName);
    if (! deps.empty()) {
        QMap<QString, Dependence>::Iterator it;
        for (it = deps.begin(); it != deps.end(); ++it) {
            if (it.value().second == Dep_Global)  // don't want these
                continue;
            QString includeFile = it.key();
            if (includeFile.isEmpty()) {
                uError() << fileName << ": " << it.value().first << " not found";
                continue;
            }
            uDebug() << fileName << ": " << includeFile << " => " << it.value().first;
            if (ms_seenFiles.indexOf(includeFile) == -1)
+                ms_seenFiles.append(includeFile);
                feedTheModel(includeFile);
        }
    }
    ParsedFilePointer ast = ms_driver->translationUnit(fileName);
    if (ast.isNull()) {
        uError() << fileName << " not found in list of parsed files";
        return;
    }
    ms_seenFiles.append(fileName);
    CppTree2Uml modelFeeder(fileName, m_thread);
    modelFeeder.parseTranslationUnit(*ast);
}
Comment 2 Ralf Habacker 2014-06-07 09:33:46 UTC
(In reply to comment #1)
> A workaround I found is adding the line indicated with '+'.
>                ms_seenFiles.append(includeFile);

The problem is that the current file is added to the list of seen files after importing, which failed when an included file includes the current file.
Comment 3 Oliver Kellogg 2014-06-08 13:44:56 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > A workaround I found is adding the line indicated with '+'.
> >                ms_seenFiles.append(includeFile);
> 
> The problem is that the current file is added to the list of seen files
> after importing, which failed when an included file includes the current
> file.

The ms_seenFiles is designed to not support mutual #includes - but I believe you are not talking about mutual includes but rather about importFiles() being called with more than one file?

If so then IMHO we might clear ms_seenFiles in the loop in ClassImport::importFiles() :

--- a/umbrello/codeimport/classimport.cpp
+++ b/umbrello/codeimport/classimport.cpp
@@ -67,6 +67,7 @@ bool ClassImport::importFiles(const QStringList& fileNames)
     bool result = true;
     umldoc->setLoading(true);
     foreach (const QString& fileName, fileNames) {
+        ms_seenFiles.clear();
         umldoc->writeToStatusBar(i18n("Importing file: %1 Progress: %2/%3",
                                  fileName, processedFilesCount, fileNames.size()));
         if (!parseFile(fileName))

I haven't tried this out yet, though.
Comment 4 Oliver Kellogg 2014-06-09 10:56:54 UTC
Git commit 60fc217737de28fa9a3f90ea60de1efda9cce231 by Oliver Kellogg.
Committed on 09/06/2014 at 10:52.
Pushed by okellogg into branch 'master'.

(In reply to comment #2)
> (In reply to comment #1)
> > A workaround I found is adding the line indicated with '+'.
> > ms_seenFiles.append(includeFile);
>
> The problem is that the current file is added to the list of seen files
> after importing, which failed when an included file includes the current
> file.

I tested this on current clucene/src/core/CLucene git master and I confirm
your finding.
I therefore commit both comment #2 and a clean version of comment #3:

umbrello/codeimport/classimport.h
- New virtual function initPerFile() lets concrete importers provide
  initializations which are executed before each single file parsed.
  This is different from initialize() in that initialize() is executed only
  once for all files parsed.

umbrello/codeimport/classimport.cpp
- Provide empty default implementation for new function initPerFile()
- In function importFiles(), call importFile() instead of parseFile()
- In function importFile(), call initPerFile() instead of initialize()

umbrello/codeimport/cppimport.{h,cpp}
- Reimplement function initPerFile() from ClassImport.
- In function feedTheModel(), append includeFile to ms_seenFiles prior to
  calling feedTheModel(includeFile) if includeFile is not found in
  ms_seenFiles.

umbrello/codeimport/import_utils.cpp
- In function createUMLObject(), if name.startsWith("::") then remove the
  leading "::" from name, and set parentPkg to logicalView.

umbrello/model_utils.cpp
- In function findUMLObject(), if name.startsWith("::") then remove the
  leading "::" from name, and set currentObj to NULL.

M  +15   -6    umbrello/codeimport/classimport.cpp
M  +3    -1    umbrello/codeimport/classimport.h
M  +9    -1    umbrello/codeimport/cppimport.cpp
M  +3    -1    umbrello/codeimport/cppimport.h
M  +4    -1    umbrello/codeimport/import_utils.cpp
M  +10   -5    umbrello/model_utils.cpp

http://commits.kde.org/umbrello/60fc217737de28fa9a3f90ea60de1efda9cce231
Comment 5 Ralf Habacker 2014-06-09 18:32:20 UTC
Git commit 3c553a2bfa20142468d8ef27345c5acb153c219b by Ralf Habacker, on behalf of Oliver Kellogg.
Committed on 09/06/2014 at 10:52.
Pushed by habacker into branch 'KDE/4.13'.

(In reply to comment #2)
> (In reply to comment #1)
> > A workaround I found is adding the line indicated with '+'.
> > ms_seenFiles.append(includeFile);
>
> The problem is that the current file is added to the list of seen files
> after importing, which failed when an included file includes the current
> file.

I tested this on current clucene/src/core/CLucene git master and I confirm
your finding.
I therefore commit both comment #2 and a clean version of comment #3:

umbrello/codeimport/classimport.h
- New virtual function initPerFile() lets concrete importers provide
  initializations which are executed before each single file parsed.
  This is different from initialize() in that initialize() is executed only
  once for all files parsed.

umbrello/codeimport/classimport.cpp
- Provide empty default implementation for new function initPerFile()
- In function importFiles(), call importFile() instead of parseFile()
- In function importFile(), call initPerFile() instead of initialize()

umbrello/codeimport/cppimport.{h,cpp}
- Reimplement function initPerFile() from ClassImport.
- In function feedTheModel(), append includeFile to ms_seenFiles prior to
  calling feedTheModel(includeFile) if includeFile is not found in
  ms_seenFiles.

umbrello/codeimport/import_utils.cpp
- In function createUMLObject(), if name.startsWith("::") then remove the
  leading "::" from name, and set parentPkg to logicalView.

umbrello/model_utils.cpp
- In function findUMLObject(), if name.startsWith("::") then remove the
  leading "::" from name, and set currentObj to NULL.
FIXED-IN:4.13.3
(cherry picked from commit 60fc217737de28fa9a3f90ea60de1efda9cce231)

M  +15   -6    umbrello/codeimport/classimport.cpp
M  +3    -1    umbrello/codeimport/classimport.h
M  +9    -1    umbrello/codeimport/cppimport.cpp
M  +3    -1    umbrello/codeimport/cppimport.h
M  +4    -1    umbrello/codeimport/import_utils.cpp
M  +10   -5    umbrello/model_utils.cpp

http://commits.kde.org/umbrello/3c553a2bfa20142468d8ef27345c5acb153c219b