Bug 254261

Summary: Crash on startup when opening session with two projects
Product: [Applications] kdevelop Reporter: ce
Component: generalAssignee: kdevelop-bugs-null
Status: RESOLVED FIXED    
Severity: crash CC: ab4bd, cordlandwehr, gotletter, jimmy, markus.hauser, niko.sams
Priority: NOR    
Version: 4.0.90   
Target Milestone: 4.1.0   
Platform: Ubuntu   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: New crash information added by DrKonqi

Description ce 2010-10-15 14:29:03 UTC
Application: kdevelop (4.0.90)
KDE Platform Version: 4.4.2 (KDE 4.4.2)
Qt Version: 4.6.2
Operating System: Linux 2.6.32-25-generic i686
Distribution: Ubuntu 10.04.1 LTS

-- Information about the crash:
most recent git version from 4.1/1.1 branch with kde 4.4.

Happens with different sessions.

The crash can be reproduced every time.

 -- Backtrace:
Application: KDevelop (kdevelop), signal: Segmentation fault
[Current thread is 1 (Thread 0xb77f4710 (LWP 1857))]

Thread 3 (Thread 0xb5860b70 (LWP 1858)):
#0  0x00b9a422 in __kernel_vsyscall ()
#1  0x007cf342 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib/tls/i686/cmov/libpthread.so.0
#2  0x0374c20f in QWaitCondition::wait(QMutex*, unsigned long) () from /usr/lib/libQtCore.so.4
#3  0x017721e8 in KDevelop::DUChainPrivate::CleanupThread::run (this=0xa1f4308) at /home/christoph/kdesvn/git/kdevplatform/language/duchain/duchain.cpp:286
#4  0x0374b32e in ?? () from /usr/lib/libQtCore.so.4
#5  0x007ca96e in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#6  0x00ad4a4e in clone () from /lib/tls/i686/cmov/libc.so.6

Thread 2 (Thread 0xb43f9b70 (LWP 1868)):
#0  0x00b9a422 in __kernel_vsyscall ()
#1  0x00ac6b86 in poll () from /lib/tls/i686/cmov/libc.so.6
#2  0x09dcd4eb in g_poll () from /lib/libglib-2.0.so.0
#3  0x09dc00ac in ?? () from /lib/libglib-2.0.so.0
#4  0x09dc04b8 in g_main_context_iteration () from /lib/libglib-2.0.so.0
#5  0x0387960f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQtCore.so.4
#6  0x0384c059 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQtCore.so.4
#7  0x0384c4aa in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQtCore.so.4
#8  0x037485a8 in QThread::exec() () from /usr/lib/libQtCore.so.4
#9  0x0188a427 in KDevelop::CompletionWorkerThread::run (this=0xa34e550) at /home/christoph/kdesvn/git/kdevplatform/language/codecompletion/codecompletionmodel.cpp:81
#10 0x0374b32e in ?? () from /usr/lib/libQtCore.so.4
#11 0x007ca96e in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#12 0x00ad4a4e in clone () from /lib/tls/i686/cmov/libc.so.6

Thread 1 (Thread 0xb77f4710 (LWP 1857)):
[KCrash Handler]
#5  0x03801bd9 in QUrl::fragment() const () from /usr/lib/libQtCore.so.4
#6  0x00e05505 in KUrl::hasSubUrl() const () from /usr/lib/libkdecore.so.5
#7  0x001e2ac5 in ?? () from /usr/lib/libkio.so.5
#8  0x001d60ea in KIO::listDir(KUrl const&, QFlags<KIO::JobFlag>, bool) () from /usr/lib/libkio.so.5
#9  0x080267c1 in GenericManagerListJob::startNextJob (this=0xa2d7e98) at /home/christoph/kdesvn/git/kdevplatform/plugins/genericprojectmanager/genericmanagerlistjob.cpp:61
#10 0x08026baf in GenericManagerListJob::qt_metacall (this=0xa2d7e98, _c=QMetaObject::InvokeMetaMethod, _id=5, _a=0xa44b9e8)
    at /home/christoph/kdesvn/build/git/kdevplatform/plugins/genericprojectmanager/genericmanagerlistjob.moc:93
#11 0x03852c9a in QMetaObject::metacall(QObject*, QMetaObject::Call, int, void**) () from /usr/lib/libQtCore.so.4
#12 0x0385d336 in QMetaCallEvent::placeMetaCall(QObject*) () from /usr/lib/libQtCore.so.4
#13 0x0385e3fe in QObject::event(QEvent*) () from /usr/lib/libQtCore.so.4
#14 0x026474dc in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#15 0x0264e05e in QApplication::notify(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#16 0x04517f2a in KApplication::notify(QObject*, QEvent*) () from /usr/lib/libkdeui.so.5
#17 0x0384da3b in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4
#18 0x03850473 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/libQtCore.so.4
#19 0x038505dd in QCoreApplication::sendPostedEvents(QObject*, int) () from /usr/lib/libQtCore.so.4
#20 0x03879adf in ?? () from /usr/lib/libQtCore.so.4
#21 0x09dbc5e5 in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#22 0x09dc02d8 in ?? () from /lib/libglib-2.0.so.0
#23 0x09dc04b8 in g_main_context_iteration () from /lib/libglib-2.0.so.0
#24 0x038795d5 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQtCore.so.4
#25 0x02707135 in ?? () from /usr/lib/libQtGui.so.4
#26 0x0384c059 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQtCore.so.4
#27 0x0384c4aa in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQtCore.so.4
#28 0x0385069f in QCoreApplication::exec() () from /usr/lib/libQtCore.so.4
#29 0x02647577 in QApplication::exec() () from /usr/lib/libQtGui.so.4
#30 0x08050b9d in main (argc=1, argv=0xbfb1b7a4) at /home/christoph/kdesvn/git/kdevelop/app/main.cpp:380

Possible duplicates by query: bug 224337, bug 223664, bug 215175, bug 214569.

Reported using DrKonqi
Comment 1 Milian Wolff 2010-10-16 05:16:16 UTC
please run kdev through valgrind and show me the output
Comment 2 ce 2010-10-18 14:01:58 UTC
valgrind log as requested:

kdevelop(4179)/kdevplatform (genericprojectmanager) GenericProjectManager::addJobItems: reading entries of KUrl("file:///home/christoph/www/vps/views/")
kdevelop(4179)/kdevplatform (genericprojectmanager) GenericProjectManager::addJobItems: reading entries of KUrl("file:///home/christoph/www/unicope/Vpc/Unicope/")
==4179== Invalid read of size 4
==4179==    at 0x671D15D: KDevelop::ProjectBaseItem::d_func() const (projectmodel.h:205)
==4179==    by 0x67198CC: KDevelop::ProjectBaseItem::url() const (projectmodel.cpp:353)
==4179==    by 0xDCE07A3: GenericManagerListJob::startNextJob() (genericmanagerlistjob.cpp:61)
==4179==    by 0xDCE0BAE: GenericManagerListJob::qt_metacall(QMetaObject::Call, int, void**) (genericmanagerlistjob.moc:93)
==4179==    by 0x5512C99: QMetaObject::metacall(QObject*, QMetaObject::Call, int, void**) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x551D335: QMetaCallEvent::placeMetaCall(QObject*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x551E3FD: QObject::event(QEvent*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x57714DB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x577805D: QApplication::notify(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x5154F29: KApplication::notify(QObject*, QEvent*) (in /usr/lib/libkdeui.so.5.4.0)
==4179==    by 0x550DA3A: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x5510472: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==  Address 0xc0185b4 is 0 bytes after a block of size 4 free'd
==4179==    at 0x4024851: operator delete(void*) (vg_replace_malloc.c:387)
==4179==    by 0x58FAB9E: ??? (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x58FABE6: ??? (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x58F8533: QPainterPath::toFillPolygon(QTransform const&) const (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x58F8641: QPainterPath::toFillPolygon(QMatrix const&) const (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x59A030B: ??? (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x58DC6F3: ??? (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x58DC7BB: ??? (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x58E2DC3: QPainter::setClipRegion(QRegion const&, Qt::ClipOperation) (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x57D7F26: QWidgetPrivate::paintBackground(QPainter*, QRegion const&, int) const (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x57D8EDC: QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x59AF88F: ??? (in /usr/lib/libQtGui.so.4.6.2)
==4179== 
==4179== Invalid read of size 4
==4179==    at 0x54BB919: QUrl::QUrl(QUrl const&) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x4117EA8: KUrl::KUrl(KUrl const&) (in /usr/lib/libkdecore.so.5.4.0)
==4179==    by 0x67198E3: KDevelop::ProjectBaseItem::url() const (projectmodel.cpp:354)
==4179==    by 0xDCE07A3: GenericManagerListJob::startNextJob() (genericmanagerlistjob.cpp:61)
==4179==    by 0xDCE0BAE: GenericManagerListJob::qt_metacall(QMetaObject::Call, int, void**) (genericmanagerlistjob.moc:93)
==4179==    by 0x5512C99: QMetaObject::metacall(QObject*, QMetaObject::Call, int, void**) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x551D335: QMetaCallEvent::placeMetaCall(QObject*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x551E3FD: QObject::event(QEvent*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x57714DB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x577805D: QApplication::notify(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x5154F29: KApplication::notify(QObject*, QEvent*) (in /usr/lib/libkdeui.so.5.4.0)
==4179==    by 0x550DA3A: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==  Address 0xc018658 is 32 bytes inside a block of size 64 free'd
==4179==    at 0x4024B3A: free (vg_replace_malloc.c:366)
==4179==    by 0x5405A5C: qFree(void*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x54C85F2: ??? (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x54BE2A7: QUrl::~QUrl() (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x4117F1C: KUrl::~KUrl() (in /usr/lib/libkdecore.so.5.4.0)
==4179==    by 0xDCE8BF9: QList<KUrl>::node_destruct(QList<KUrl>::Node*, QList<KUrl>::Node*) (qlist.h:402)
==4179==    by 0xDCE7BA1: QList<KUrl>::free(QListData::Data*) (qlist.h:646)
==4179==    by 0xDCE66E2: QList<KUrl>::~QList() (qlist.h:621)
==4179==    by 0xDCE64CC: KUrl::List::~List() (kurl.h:126)
==4179==    by 0xDCE3C16: GenericProjectManager::addJobItems(KDevelop::ProjectFolderItem*, QList<KIO::UDSEntry> const&, bool) (genericmanager.cpp:273)
==4179==    by 0xDCE5DE2: GenericProjectManager::qt_metacall(QMetaObject::Call, int, void**) (genericmanager.moc:103)
==4179==    by 0x5512C99: QMetaObject::metacall(QObject*, QMetaObject::Call, int, void**) (in /usr/lib/libQtCore.so.4.6.2)
==4179== 
==4179== Invalid read of size 4
==4179==    at 0x54BB921: QUrl::QUrl(QUrl const&) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x4117EA8: KUrl::KUrl(KUrl const&) (in /usr/lib/libkdecore.so.5.4.0)
==4179==    by 0x67198E3: KDevelop::ProjectBaseItem::url() const (projectmodel.cpp:354)
==4179==    by 0xDCE07A3: GenericManagerListJob::startNextJob() (genericmanagerlistjob.cpp:61)
==4179==    by 0xDCE0BAE: GenericManagerListJob::qt_metacall(QMetaObject::Call, int, void**) (genericmanagerlistjob.moc:93)
==4179==    by 0x5512C99: QMetaObject::metacall(QObject*, QMetaObject::Call, int, void**) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x551D335: QMetaCallEvent::placeMetaCall(QObject*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x551E3FD: QObject::event(QEvent*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==    by 0x57714DB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x577805D: QApplication::notify(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.6.2)
==4179==    by 0x5154F29: KApplication::notify(QObject*, QEvent*) (in /usr/lib/libkdeui.so.5.4.0)
==4179==    by 0x550DA3A: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib/libQtCore.so.4.6.2)
==4179==  Address 0x2f777777 is not stack'd, malloc'd or (recently) free'd
==4179== 
KCrash: Application 'kdevelop' crashing...
sock_file=/home/christoph/.kde4-svn/socket-christoph-linux/kdeinit4__0
Warning: connect() failed: : No such file or directory
==4179== Warning: invalid file descriptor -1 in syscall write()
==4179== Warning: invalid file descriptor -1 in syscall write()
==4179== Warning: invalid file descriptor -1 in syscall read()
KCrash cannot reach kdeinit, launching directly.

[1]+  Stopped                 valgrind kdevelop -s unicope
Comment 3 Niko Sams 2010-10-19 14:15:01 UTC
Milian, do you have any idea what's the problem here?
Comment 4 Milian Wolff 2010-10-19 15:28:14 UTC
no not yet, but it looks like a reference got stored in the project item, but the referenced item got deleted when the context was exited...

have to double check that though to make sure...
Comment 5 Milian Wolff 2010-10-21 20:30:59 UTC
*** Bug 254834 has been marked as a duplicate of this bug. ***
Comment 6 Milian Wolff 2010-10-21 20:32:24 UTC
related / duplicate of bug 224337 - but keeping open for useful information...
Comment 7 Niko Sams 2010-10-21 20:46:45 UTC
It must be somehow related to the relatively slow NFS share the projects reside on. (this and bug 224337)
Comment 8 Milian Wolff 2010-10-22 04:56:33 UTC
commit 7fb40ea15ce361c62f910715b839dc44b08a0405
Author: Milian Wolff <mail@milianw.de>
Date:   Fri Oct 22 04:57:15 2010 +0200

    only append subdirs to actual parent list jobs, fixes random crashes
    
    before we used sig/slot (for no reason?) and that way each dir was appended to *all* running import jobs
    this lead to the jobs filtering and deleting their items and leading to various crashes
    
    BUG: 254261
    
    TODO: backport fix to 4.1

diff --git a/plugins/genericprojectmanager/test/reloadtest.cpp b/plugins/genericprojectmanager/test/reloadtest.cpp
index f4098fb..9ef09ca 100644
--- a/plugins/genericprojectmanager/test/reloadtest.cpp
+++ b/plugins/genericprojectmanager/test/reloadtest.cpp
@@ -66,7 +66,7 @@ void ProjectLoadTest::cleanup()
     delete m_core;
 }
 
-void ProjectLoadTest::addRemoveFiles()
+QPair<QString, KUrl> makeProject()
 {
     QString path;
     QString projectName;
@@ -88,33 +88,40 @@ void ProjectLoadTest::addRemoveFiles()
     projectFile.write(projectFileContents.join("\n").toAscii());
     projectFile.close();
 
-    QFile f(path+"/sdf");
+    return qMakePair(path, projecturl);
+}
+
+void ProjectLoadTest::addRemoveFiles()
+{
+    const QPair<QString, KUrl> p = makeProject();
+
+    QFile f(p.first+"/sdf");
     f.open(QIODevice::WriteOnly);
     f.close();
 
-    KDevelop::ICore::self()->projectController()->openProject(projecturl);
+    KDevelop::ICore::self()->projectController()->openProject(p.second);
     QTest::qWait(500);
 
     KDevelop::IProject* project = KDevelop::ICore::self()->projectController()->projects().first();
-    Q_ASSERT(project->projectFileUrl() == projecturl);
+    Q_ASSERT(project->projectFileUrl() == p.second);
 
     //KDirWatch adds/removes the file automatically
     for (int i=0; i<100; ++i) {
-        QFile f2(path+"/blub"+QString::number(i));
+        QFile f2(p.first+"/blub"+QString::number(i));
         f2.open(QIODevice::WriteOnly);
         f2.close();
     }
     for (int i=0; i<50; ++i) {
-        QFile f2(path+"/blub"+QString::number(i));
+        QFile f2(p.first+"/blub"+QString::number(i));
         f2.remove();
     }
     QTest::qWait(500);
 
-    QCOMPARE(project->filesForUrl(path+"/blub"+QString::number(50)).count(), 1);
-    KDevelop::ProjectFileItem* file = project->filesForUrl(path+"/blub"+QString::number(50)).first();
+    QCOMPARE(project->filesForUrl(p.first+"/blub"+QString::number(50)).count(), 1);
+    KDevelop::ProjectFileItem* file = project->filesForUrl(p.first+"/blub"+QString::number(50)).first();
     project->projectFileManager()->removeFilesAndFolders(QList<KDevelop::ProjectBaseItem*>() << file ); //message box has to be accepted manually :(
     for (int i=51; i<100; ++i) {
-        QFile f2(path+"/blub"+QString::number(i));
+        QFile f2(p.first+"/blub"+QString::number(i));
         f2.remove();
     }
 
@@ -124,9 +131,8 @@ void ProjectLoadTest::addRemoveFiles()
     foreach (KDevelop::IProject *p, KDevelop::ICore::self()->projectController()->projects()) {
         KDevelop::ICore::self()->projectController()->closeProject(p);
     }
-
     QTest::qWait(500);
-    exec("rm -r "+path);
+    exec("rm -r "+p.first);
 }
 
 void _writeRandomStructure(QString path, int files)
@@ -153,47 +159,55 @@ void _writeRandomStructure(QString path, int files)
     }
 }
 
-void ProjectLoadTest::addLotsOfFiles()
+void fillProject(int filesPerDir, int Dirs, const QPair<QString, KUrl> project, bool wait)
 {
-    QString path;
-    QString projectName;
-    do {
-        projectName = QString("testproject%1").arg(qrand());
-        path = QDir::currentPath().append("/").append(projectName);
-    } while(QFile::exists(path));
-    QDir::current().mkdir(projectName);
-
-    QDir::setCurrent(path);
-
-    QStringList projectFileContents;
-    projectFileContents
-    << "[Project]"
-    << QString("Name=") + projectName
-    << "Manager=KDevGenericManager";
+    QDir(project.first).mkdir("foou");
+    _writeRandomStructure(project.first+"/foou", 50);
+    for(int i=0; i < 100; ++i) {
+        exec("bash -c \"cp -r foou foox"+QString::number(i)+" > /dev/null 2>&1 & \"");
+        if (wait) {
+            QTest::qWait(100);
+        }
+    }
+}
 
-    KUrl projecturl( path + "/simpleproject.kdev4" );
-    QFile projectFile(projecturl.toLocalFile());
-    projectFile.open(QIODevice::WriteOnly);
-    projectFile.write(projectFileContents.join("\n").toAscii());
-    projectFile.close();
+void ProjectLoadTest::addLotsOfFiles()
+{
+    QPair<QString, KUrl> p = makeProject();
 
-    KDevelop::ICore::self()->projectController()->openProject(projecturl);
+    KDevelop::ICore::self()->projectController()->openProject(p.second);
     QTest::qWait(2000);
 
     KDevelop::IProject* project = KDevelop::ICore::self()->projectController()->projects().first();
-    Q_ASSERT(project->projectFileUrl() == projecturl);
+    Q_ASSERT(project->projectFileUrl() == p.second);
 
-    QDir(path).mkdir("foou");
-    _writeRandomStructure(path+"/foou", 50);
-    for(int i=0; i < 100; ++i) {
-        exec("bash -c \"cp -r foou foox"+QString::number(i)+" > /dev/null 2>&1 & \"");
-        QTest::qWait(100);
+    fillProject(50, 100, p, true);
+
+    foreach (KDevelop::IProject *p, KDevelop::ICore::self()->projectController()->projects()) {
+        KDevelop::ICore::self()->projectController()->closeProject(p);
     }
 
+    QTest::qWait(500);
+    exec("rm -r "+p.first);
+}
+
+void ProjectLoadTest::addMultipleJobs()
+{
+    QPair<QString, KUrl> p1 = makeProject();
+    fillProject(10, 25, p1, false);
+    QPair<QString, KUrl> p2 = makeProject();
+    fillProject(10, 25, p2, false);
+
+    KDevelop::ICore::self()->projectController()->openProject(p1.second);
+    KDevelop::ICore::self()->projectController()->openProject(p2.second);
+
+    QTest::qWait(2000);
+
     foreach (KDevelop::IProject *p, KDevelop::ICore::self()->projectController()->projects()) {
         KDevelop::ICore::self()->projectController()->closeProject(p);
     }
 
     QTest::qWait(500);
-    exec("rm -r "+path);
+    exec("rm -r "+p1.first);
+    exec("rm -r "+p2.first);
 }
diff --git a/plugins/genericprojectmanager/test/reloadtest.h b/plugins/genericprojectmanager/test/reloadtest.h
index 317ce4c..f07c662 100644
--- a/plugins/genericprojectmanager/test/reloadtest.h
+++ b/plugins/genericprojectmanager/test/reloadtest.h
@@ -37,6 +37,8 @@ private slots:
 
   void addRemoveFiles();
   void addLotsOfFiles();
+  void addMultipleJobs();
+
 private:
   KDevelop::TestCore* m_core;
 };
diff --git a/project/abstractfilemanagerplugin.cpp b/project/abstractfilemanagerplugin.cpp
index 0b79e36..9b40e6c 100644
--- a/project/abstractfilemanagerplugin.cpp
+++ b/project/abstractfilemanagerplugin.cpp
@@ -75,7 +75,8 @@ struct AbstractFileManagerPlugin::Private {
     /// @p forceRecursion if true, existing folders will be re-read no matter what
     KJob* eventuallyReadFolder( ProjectFolderItem* item,
                                 const bool forceRecursion = false );
-    void addJobItems(ProjectFolderItem* baseItem,
+    void addJobItems(FileManagerListJob* job,
+                     ProjectFolderItem* baseItem,
                      const KIO::UDSEntryList& entries,
                      const bool forceRecursion);
 
@@ -111,9 +112,9 @@ void AbstractFileManagerPlugin::Private::projectClosing(IProject* project)
 }
 
 KJob* AbstractFileManagerPlugin::Private::eventuallyReadFolder( ProjectFolderItem* item,
-                                                                const bool forceResursion )
+                                                                const bool forceRecursion )
 {
-    FileManagerListJob* listJob = new FileManagerListJob( item, forceResursion );
+    FileManagerListJob* listJob = new FileManagerListJob( item, forceRecursion );
     m_projectJobs[ item->project() ] << listJob;
     kDebug() << "adding job" << listJob << item->url() << "for project" << item->project();
 
@@ -122,11 +123,8 @@ KJob* AbstractFileManagerPlugin::Private::eventuallyReadFolder( ProjectFolderIte
     q->connect( listJob, SIGNAL(finished(KJob*)),
                 q, SLOT(jobFinished(KJob*)) );
 
-    q->connect( listJob, SIGNAL(entries(ProjectFolderItem*, KIO::UDSEntryList, bool)),
-                q, SLOT(addJobItems(ProjectFolderItem*, KIO::UDSEntryList, bool)) );
-
-    q->connect( q, SIGNAL(appendSubDir(ProjectFolderItem*)),
-                listJob, SLOT(addSubDir(ProjectFolderItem*)));
+    q->connect( listJob, SIGNAL(entries(FileManagerListJob*, ProjectFolderItem*, KIO::UDSEntryList, bool)),
+                q, SLOT(addJobItems(FileManagerListJob*, ProjectFolderItem*, KIO::UDSEntryList, bool)) );
 
     return listJob;
 }
@@ -139,7 +137,8 @@ void AbstractFileManagerPlugin::Private::jobFinished(KJob* job)
     m_projectJobs[ gmlJob->item()->project() ].removeOne( job );
 }
 
-void AbstractFileManagerPlugin::Private::addJobItems(ProjectFolderItem* baseItem,
+void AbstractFileManagerPlugin::Private::addJobItems(FileManagerListJob* job,
+                                                     ProjectFolderItem* baseItem,
                                                      const KIO::UDSEntryList& entries,
                                                      const bool forceRecursion)
 {
@@ -202,7 +201,7 @@ void AbstractFileManagerPlugin::Private::addJobItems(ProjectFolderItem* baseItem
                 folders.removeAt( index );
                 if ( forceRecursion ) {
                     //no need to add this item, but we still want to recurse into it
-                    emit q->appendSubDir( f );
+                    job->addSubDir( f );
                 }
             }
         } else if ( baseItem->child(j)->type() == ProjectBaseItem::File ) {
@@ -229,7 +228,7 @@ void AbstractFileManagerPlugin::Private::addJobItems(ProjectFolderItem* baseItem
     foreach ( const KUrl& url, folders ) {
         ProjectFolderItem* folder = q->createFolderItem( baseItem->project(), url, baseItem );
         emit q->folderAdded( folder );
-        emit q->appendSubDir( folder );
+        job->addSubDir( folder );
     }
 }
 
diff --git a/project/abstractfilemanagerplugin.h b/project/abstractfilemanagerplugin.h
index 84efda4..409f092 100644
--- a/project/abstractfilemanagerplugin.h
+++ b/project/abstractfilemanagerplugin.h
@@ -29,6 +29,8 @@
 
 namespace KDevelop {
 
+class FileManagerListJob;
+
 /**
  * This class can be used as a common base for file managers.
  *
@@ -90,9 +92,6 @@ protected:
                                              KDevelop::ProjectBaseItem* parent);
 
 Q_SIGNALS:
-    ///TODO: mark private
-    void appendSubDir(ProjectFolderItem* item );
-
     void folderAdded(KDevelop::ProjectFolderItem* folder);
     void folderRemoved(KDevelop::ProjectFolderItem* folder);
     void folderRenamed(const KUrl& oldFolder, KDevelop::ProjectFolderItem* newFolder);
@@ -108,7 +107,8 @@ private:
 
     Q_PRIVATE_SLOT(d, KJob* eventuallyReadFolder( ProjectFolderItem* item,
                                                   const bool forceRecursion = false ))
-    Q_PRIVATE_SLOT(d, void addJobItems(ProjectFolderItem* baseItem,
+    Q_PRIVATE_SLOT(d, void addJobItems(FileManagerListJob* job,
+                                       ProjectFolderItem* baseItem,
                                        const KIO::UDSEntryList& entries,
                                        const bool forceRecursion))
 
diff --git a/project/filemanagerlistjob.cpp b/project/filemanagerlistjob.cpp
index f97659e..38912cd 100644
--- a/project/filemanagerlistjob.cpp
+++ b/project/filemanagerlistjob.cpp
@@ -45,6 +45,8 @@ ProjectFolderItem* FileManagerListJob::item() const
 
 void FileManagerListJob::addSubDir( ProjectFolderItem* item )
 {
+    Q_ASSERT(!m_item || item->url().upUrl() == m_item->url());
+
     m_listQueue.enqueue(item);
 }
 
@@ -59,6 +61,7 @@ void FileManagerListJob::startNextJob()
     if ( m_listQueue.isEmpty() ) {
         return;
     }
+
     m_item = m_listQueue.dequeue();
     KIO::ListJob* job = KIO::listDir( m_item->url(), KIO::HideProgressInfo );
     job->setParentJob( this );
@@ -69,7 +72,7 @@ void FileManagerListJob::startNextJob()
 
 void FileManagerListJob::slotResult(KJob* job)
 {
-    emit entries(m_item, entryList, m_forceRecursion);
+    emit entries(this, m_item, entryList, m_forceRecursion);
     entryList.clear();
 
     if( job->error() ) {
diff --git a/project/filemanagerlistjob.h b/project/filemanagerlistjob.h
index c1a1147..4bb9b36 100644
--- a/project/filemanagerlistjob.h
+++ b/project/filemanagerlistjob.h
@@ -35,14 +35,16 @@ public:
     FileManagerListJob(ProjectFolderItem* item, const bool forceRecursion);
     ProjectFolderItem* item() const;
 
+    void addSubDir(ProjectFolderItem* item);
+
 signals:
-    void entries(ProjectFolderItem* baseItem, const KIO::UDSEntryList& entries, const bool forceRecursion);
+    void entries(FileManagerListJob* job, ProjectFolderItem* baseItem,
+                 const KIO::UDSEntryList& entries, const bool forceRecursion);
     void nextJob();
 
 private slots:
     void slotEntries(KIO::Job* job, const KIO::UDSEntryList& entriesIn );
     void slotResult(KJob* job);
-    void addSubDir(ProjectFolderItem* item);
     void startNextJob();
 
 private:
Comment 9 Niko Sams 2010-10-27 10:05:32 UTC
could you backport the fix *please*
Comment 10 Milian Wolff 2010-10-27 21:09:06 UTC
done
Comment 11 George L. Emigh 2010-11-02 19:24:04 UTC
Created attachment 53075 [details]
New crash information added by DrKonqi

kdevelop (4.1.0) on KDE Platform 4.5.2 (KDE 4.5.2) using Qt 4.6.3

I'm using 4.1 from the ebuild provided by Gentoo, if I have 2 open projects when I exit, it will crash when I start kdevelop again.

-- Backtrace (Reduced):
#6  0x00007fbbf51a68cb in QUrl::QUrl(QUrl const&) () from /usr/lib64/qt4/libQtCore.so.4
#7  0x00007fbbf64056e9 in KUrl::KUrl(KUrl const&) () from /usr/lib/libkdecore.so.5
#8  0x00007fbbf1ed0f91 in KDevelop::ProjectBaseItem::url (this=<value optimized out>) at /var/tmp/portage/dev-util/kdevplatform-1.1.0/work/kdevplatform-1.1.0/project/projectmodel.cpp:354
#9  0x00007fbbe0074399 in GenericManagerListJob::startNextJob (this=0x18376d0)
    at /var/tmp/portage/dev-util/kdevplatform-1.1.0/work/kdevplatform-1.1.0/plugins/genericprojectmanager/genericmanagerlistjob.cpp:61
#10 0x00007fbbe00744a4 in GenericManagerListJob::qt_metacall (this=0x18376d0, _c=QMetaObject::InvokeMetaMethod, _id=<value optimized out>, _a=0x37ee880)
    at /var/tmp/portage/dev-util/kdevplatform-1.1.0/work/kdevplatform-1.1.0_build/plugins/genericprojectmanager/genericmanagerlistjob.moc:93
Comment 12 Niko Sams 2010-11-02 19:55:38 UTC
George, the crash will be fixed in 4.1.1, you can already use the 4.1 branch from git.
Comment 13 Milian Wolff 2010-11-06 20:13:11 UTC
*** Bug 256247 has been marked as a duplicate of this bug. ***
Comment 14 Milian Wolff 2010-11-21 16:51:48 UTC
*** Bug 246517 has been marked as a duplicate of this bug. ***
Comment 15 Milian Wolff 2010-11-25 21:09:02 UTC
*** Bug 257860 has been marked as a duplicate of this bug. ***