Bug 140417 - Crash Digikam when delete image
Summary: Crash Digikam when delete image
Status: RESOLVED WORKSFORME
Alias: None
Product: digikam
Classification: Applications
Component: Albums-Trash (show other bugs)
Version: unspecified
Platform: Ubuntu Linux
: NOR crash
Target Milestone: ---
Assignee: Digikam Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-01-22 02:22 UTC by Geoff King
Modified: 2020-08-13 15:52 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In: 0.9.1


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Geoff King 2007-01-22 02:22:51 UTC
Version:           0.9.1-svn (using KDE KDE 3.5.5)
Installed from:    Ubuntu Packages
OS:                Linux

When using the right click menu to 'move to trash' the program has crashed often.  This happens from the thumbnail view.  The files do get deleted/moved to grash.  I'm using yesterday's SVN version.

Backtrace 1:
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
[Thread debugging using libthread_db enabled]
[New Thread -1246009152 (LWP 5228)]
[New Thread -1255941216 (LWP 5459)]
[KCrash handler]
#9  0xb63a33b0 in QString::length () from /usr/lib/libqt-mt.so.3
#10 0xb6795d85 in QString::operator+= () from /usr/lib/libqt-mt.so.3
#11 0xb7cdf4ab in Digikam::ImageInfo::filePath ()
   from /usr/lib/libdigikam.so.0
#12 0xb7dd9da4 in Digikam::ImageDescEditTab::slotApplyAllChanges ()
   from /usr/lib/libdigikam.so.0
#13 0xb7dd9f98 in Digikam::ImageDescEditTab::setItem ()
   from /usr/lib/libdigikam.so.0
#14 0xb7de053e in Digikam::ImagePropertiesSideBarDB::slotChangedTab ()
   from /usr/lib/libdigikam.so.0
#15 0xb7ddfbc0 in Digikam::ImagePropertiesSideBarDB::itemChanged ()
   from /usr/lib/libdigikam.so.0
#16 0xb7cceeb6 in Digikam::DigikamView::slotDispatchImageSelected ()
   from /usr/lib/libdigikam.so.0
#17 0xb7ccfd0f in Digikam::DigikamView::qt_invoke ()
   from /usr/lib/libdigikam.so.0
#18 0xb647a957 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3
#19 0xb647b3fc in QObject::activate_signal () from /usr/lib/libqt-mt.so.3
#20 0xb680900a in QTimer::timeout () from /usr/lib/libqt-mt.so.3
#21 0xb64a2662 in QTimer::event () from /usr/lib/libqt-mt.so.3
#22 0xb6411b88 in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3
#23 0xb64139b7 in QApplication::notify () from /usr/lib/libqt-mt.so.3
#24 0xb6bdadb2 in KApplication::notify () from /usr/lib/libkdecore.so.4
#25 0xb63a4389 in QApplication::sendEvent () from /usr/lib/libqt-mt.so.3
#26 0xb64045d3 in QEventLoop::activateTimers () from /usr/lib/libqt-mt.so.3
#27 0xb63b8ec5 in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3
#28 0xb642c25e in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3
#29 0xb642c06e in QEventLoop::exec () from /usr/lib/libqt-mt.so.3
#30 0xb6413731 in QApplication::exec () from /usr/lib/libqt-mt.so.3
#31 0x0804ab3c in main ()


Backtrace 2:
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
[Thread debugging using libthread_db enabled]
[New Thread -1246132032 (LWP 7804)]
[KCrash handler]
#9  0xb6b20639 in KURL::~KURL () from /usr/lib/libkdecore.so.4
#10 0xb7c70332 in QValueListPrivate<KURL>::~QValueListPrivate ()
   from /usr/lib/libdigikam.so.0
#11 0xb70e217d in KIO::TransferJob::~TransferJob () from /usr/lib/libkio.so.4
#12 0xb645c020 in QObject::event () from /usr/lib/libqt-mt.so.3
#13 0xb63f3b88 in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3
#14 0xb63f59b7 in QApplication::notify () from /usr/lib/libqt-mt.so.3
#15 0xb6bbcdb2 in KApplication::notify () from /usr/lib/libkdecore.so.4
#16 0xb6386389 in QApplication::sendEvent () from /usr/lib/libqt-mt.so.3
#17 0xb63f4bc0 in QApplication::sendPostedEvents ()
   from /usr/lib/libqt-mt.so.3
#18 0xb63f4cc8 in QApplication::sendPostedEvents ()
   from /usr/lib/libqt-mt.so.3
#19 0xb639a27d in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3
#20 0xb640e25e in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3
#21 0xb640e06e in QEventLoop::exec () from /usr/lib/libqt-mt.so.3
#22 0xb63f5731 in QApplication::exec () from /usr/lib/libqt-mt.so.3
#23 0x0804ab3c in main ()
Comment 1 Marcel Wiesweg 2007-01-22 17:01:36 UTC
SVN commit 626246 by mwiesweg:

Give only ImageInfo copies to right side bar in main view.
We cannot well control the point when the original ImageInfos are deleted
in AlbumLister, so make sure that the side bar does not sit on invalid data.
This may be the cause for the crash in 140417 - please test if you can reproduce the crash.

CCBUG: 140417


 M  +2 -1      NEWS  
 M  +10 -3     digikam/albumiconview.cpp  
 M  +1 -1      digikam/albumiconview.h  
 M  +5 -2      digikam/digikamview.cpp  
 M  +5 -0      libs/imageproperties/imagepropertiessidebardb.cpp  
 M  +1 -0      libs/imageproperties/imagepropertiessidebardb.h  


--- trunk/extragear/graphics/digikam/NEWS #626245:626246
@@ -464,6 +464,7 @@
 270 ==> 130237 : Typos in digiKam plugin files.
 271 ==> 138925 : External modules config dialog lacks a select all button.
 272 ==> 140038 : digiKam Image Editor crash on right click after changing toolbar.
-273 ==> 
+273 ==> 139766 : Crash when displaying EXIF metadata with Unicode comment
+274 ==> 
 
 ---------------------------------------------------------------------------------------------------- 
--- trunk/extragear/graphics/digikam/digikam/albumiconview.cpp #626245:626246
@@ -857,6 +857,9 @@
     KIO::Job* job = DIO::del(urlList, useTrash);
     connect(job, SIGNAL(result(KIO::Job*)),
             this, SLOT(slotDIOResult(KIO::Job*)));
+
+    // The AlbumManager KDirWatch will trigger a DIO::scan.
+    // When this is completed, DIO will call AlbumLister::instance()->refresh().
 }
 
 void AlbumIconView::slotDeleteSelectedItemsDirectly(bool useTrash)
@@ -1391,7 +1394,7 @@
     return itemList;
 }
 
-QPtrList<ImageInfo> AlbumIconView::selectedImageInfos() const
+QPtrList<ImageInfo> AlbumIconView::selectedImageInfos(bool copy) const
 {
     // Returns the list of ImageInfos of currently selected items,
     // with the extra feature that the currentItem is the first in the list.
@@ -1401,10 +1404,14 @@
         AlbumIconItem *iconItem = static_cast<AlbumIconItem *>(it);
         if (it->isSelected())
         {
+            ImageInfo *info = iconItem->imageInfo();
+            if (copy)
+                info = new ImageInfo(*info);
+
             if (iconItem == currentItem())
-                list.prepend(iconItem->imageInfo());
+                list.prepend(info);
             else
-                list.append(iconItem->imageInfo());
+                list.append(info);
         }
     }
     return list;
--- trunk/extragear/graphics/digikam/digikam/albumiconview.h #626245:626246
@@ -81,7 +81,7 @@
     KURL::List allItems();
     KURL::List selectedItems();
 
-    QPtrList<ImageInfo> selectedImageInfos() const;
+    QPtrList<ImageInfo> selectedImageInfos(bool copy) const;
 
     void refresh();
     void refreshItems(const KURL::List& itemList);
--- trunk/extragear/graphics/digikam/digikam/digikamview.cpp #626245:626246
@@ -621,12 +621,13 @@
     d->selectionTimer->start(75, true);
 }
 
+
 void DigikamView::slotDispatchImageSelected()
 {
     if (d->needDispatchSelection)
     {
-        // the list of ImageInfos of currently selected items, currentItem first
-        QPtrList<ImageInfo> list = d->iconView->selectedImageInfos();
+        // the list of copies of ImageInfos of currently selected items, currentItem first
+        QPtrList<ImageInfo> list = d->iconView->selectedImageInfos(true );
 
         if (list.isEmpty())
         {
@@ -643,6 +644,8 @@
                 AlbumIconItem *selectedItem = d->iconView->firstSelectedItem();
                 d->rightSideBar->setPreviousNextState(d->iconView->firstItem() != selectedItem,
                                                       d->iconView->lastItem() != selectedItem);
+                // we fed a list of copies
+                d->rightSideBar->takeImageInfoOwnership(true);
 
                 if (!d->albumWidgetStack->previewMode() == AlbumWidgetStack::PreviewAlbumMode)
                     d->albumWidgetStack->setPreviewItem(selectedItem->imageInfo()->kurl());
--- trunk/extragear/graphics/digikam/libs/imageproperties/imagepropertiessidebardb.cpp #626245:626246
@@ -182,7 +182,12 @@
     slotChangedTab( getActiveTab() );
 }
 
+void ImagePropertiesSideBarDB::takeImageInfoOwnership(bool takeOwnership)
+{
+    d->currentInfos.setAutoDelete(takeOwnership);
+}
 
+
 void ImagePropertiesSideBarDB::slotNoCurrentItem(void)
 {
     ImagePropertiesSideBar::slotNoCurrentItem();
--- trunk/extragear/graphics/digikam/libs/imageproperties/imagepropertiessidebardb.h #626245:626246
@@ -68,6 +68,7 @@
     virtual void itemChanged(QPtrList<ImageInfo> infos);
 
     void setPreviousNextState(bool hasPrevious, bool hasNext);
+    void takeImageInfoOwnership(bool takeOwnership);
 
     void populateTags(void);
 
Comment 2 Geoff King 2007-01-23 02:48:59 UTC
I think this did help.  I'll keep testing over the next couple days. 

However, i am also noticing a crash when switching between albums. I think it happens more often when clicking quickly between different albums. See below:

Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
[Thread debugging using libthread_db enabled]
[New Thread -1246218048 (LWP 18845)]
[KCrash handler]
#9  0xb7c71612 in QString::length (this=0x882e4b4)
    at /usr/share/qt3/include/qstring.h:880
#10 0xb6762d85 in QString::operator+= () from /usr/lib/libqt-mt.so.3
#11 0x0804b19e in operator+ (s1=@0xbfeffde4, s2=@0x882e4b4)
    at /usr/share/qt3/include/qstring.h:1038
#12 0xb7ce0495 in Digikam::ImageInfo::filePath (this=0x882e4a8)
    at imageinfo.cpp:161
#13 0xb7de4b1f in Digikam::ImageDescEditTab::slotApplyAllChanges (
    this=0x8316360) at imagedescedittab.cpp:368
#14 0xb7de531f in Digikam::ImageDescEditTab::setItem (this=0x8316360, 
    info=0x0) at imagedescedittab.cpp:393
#15 0xb7dea41b in Digikam::ImagePropertiesSideBarDB::slotNoCurrentItem (
    this=0x821e9a0) at imagepropertiessidebardb.cpp:195
#16 0xb7deb0bb in Digikam::ImagePropertiesSideBarDB::qt_invoke (
    this=0x821e9a0, _id=57, _o=0xbfefff9c) at imagepropertiessidebardb.moc:154
#17 0xb6447957 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3
#18 0xb64483fc in QObject::activate_signal () from /usr/lib/libqt-mt.so.3
#19 0xb7ccf1a5 in Digikam::DigikamView::signal_noCurrentItem (this=0x81a8fc0)
    at digikamview.moc:278
#20 0xb7ccf957 in Digikam::DigikamView::slot_albumSelected (this=0x81a8fc0, 
    album=0x83de068) at digikamview.cpp:569
#21 0xb7cd0033 in Digikam::DigikamView::qt_invoke (this=0x81a8fc0, _id=83, 
    _o=0xbff00088) at digikamview.moc:321
#22 0xb6447a84 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3
#23 0xb7ca5ab7 in Digikam::AlbumManager::signalAlbumCurrentChanged (
    this=0x80d7f60, t0=0x83de068) at albummanager.moc:188
#24 0xb7ca5b10 in Digikam::AlbumManager::setCurrentAlbum (this=0x80d7f60, 
    album=0x83de068) at albummanager.cpp:688
#25 0xb7c996cf in Digikam::AlbumFolderView::slotSelectionChanged (
    this=0x833f038) at albumfolderview.cpp:418
#26 0xb7c9e776 in Digikam::AlbumFolderView::qt_invoke (this=0x833f038, 
    _id=84, _o=0xbff001dc) at albumfolderview.moc:139
#27 0xb6447957 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3
#28 0xb64483fc in QObject::activate_signal () from /usr/lib/libqt-mt.so.3
#29 0xb67ebf56 in QListView::selectionChanged () from /usr/lib/libqt-mt.so.3
#30 0xb6541e6d in QListView::setCurrentItem () from /usr/lib/libqt-mt.so.3
#31 0xb6545ca3 in QListView::contentsMousePressEventEx ()
   from /usr/lib/libqt-mt.so.3
#32 0xb65463a8 in QListView::contentsMousePressEvent ()
   from /usr/lib/libqt-mt.so.3
#33 0xb7cd5f09 in Digikam::FolderView::contentsMousePressEvent (
    this=0x833f038, e=0xbff004cc) at folderview.cpp:187
#34 0xb657d0b9 in QScrollView::viewportMousePressEvent ()
   from /usr/lib/libqt-mt.so.3
#35 0xb657e52c in QScrollView::eventFilter () from /usr/lib/libqt-mt.so.3
#36 0xb6546816 in QListView::eventFilter () from /usr/lib/libqt-mt.so.3
#37 0xb6446f04 in QObject::activate_filters () from /usr/lib/libqt-mt.so.3
#38 0xb6446f82 in QObject::event () from /usr/lib/libqt-mt.so.3
#39 0xb647e65b in QWidget::event () from /usr/lib/libqt-mt.so.3
#40 0xb63deb88 in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3
#41 0xb63e0d46 in QApplication::notify () from /usr/lib/libqt-mt.so.3
#42 0xb6ba7db2 in KApplication::notify () from /usr/lib/libkdecore.so.4
#43 0xb63713fd in QApplication::sendSpontaneousEvent ()
   from /usr/lib/libqt-mt.so.3
#44 0xb6370062 in QETWidget::translateMouseEvent ()
   from /usr/lib/libqt-mt.so.3
#45 0xb636e14c in QApplication::x11ProcessEvent () from /usr/lib/libqt-mt.so.3
#46 0xb6385320 in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3
#47 0xb63f925e in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3
#48 0xb63f906e in QEventLoop::exec () from /usr/lib/libqt-mt.so.3
#49 0xb63e0731 in QApplication::exec () from /usr/lib/libqt-mt.so.3
#50 0x0804af0f in main (argc=-1208727988, argv=0xbff01204) at main.cpp:292
Comment 3 Marcel Wiesweg 2007-01-23 17:44:41 UTC
SVN commit 626532 by mwiesweg:

Delete ImageInfo objects only after the tabs have had a chance to save their changes.
Don't use setAutoDelete, it is more explicit like this.

CCBUG: 140417


 M  +33 -1     imagepropertiessidebardb.cpp  


--- trunk/extragear/graphics/digikam/libs/imageproperties/imagepropertiessidebardb.cpp #626531:626532
@@ -65,6 +65,7 @@
         dirtyDesceditTab    = false;
         hasPrevious         = false;
         hasNext             = false;
+        hasImageInfoOwnership = false;
     }
 
     bool              dirtyDesceditTab;
@@ -75,6 +76,8 @@
 
     bool              hasPrevious;
     bool              hasNext;
+
+    bool              hasImageInfoOwnership;
 };
 
 ImagePropertiesSideBarDB::ImagePropertiesSideBarDB(QWidget *parent, const char *name, QSplitter *splitter, 
@@ -151,6 +154,16 @@
     m_currentRect        = rect;
     m_image              = img;
 
+    // The list _may_ have autoDelete set to true.
+    // Keep old ImageInfo objects from being deleted
+    // until the tab has had the chance to save changes and clear lists.
+    QPtrList<ImageInfo> temporaryList;
+    if (d->hasImageInfoOwnership)
+    {
+        temporaryList = d->currentInfos;
+        d->hasImageInfoOwnership = false;
+    }
+
     QPtrList<ImageInfo> list;
     if (info)
         list.append(info);
@@ -162,6 +175,12 @@
     d->dirtyDesceditTab  = false;
 
     slotChangedTab( getActiveTab() );
+
+    // now delete old objects, after slotChangedTab
+    for (ImageInfo *info = temporaryList.first(); info; info = temporaryList.next())
+    {
+        delete info;
+    }
 }
 
 void ImagePropertiesSideBarDB::itemChanged(QPtrList<ImageInfo> infos)
@@ -172,6 +191,14 @@
     m_currentURL         = infos.first()->kurl();
     m_currentRect        = QRect();
     m_image              = 0;
+
+    QPtrList<ImageInfo> temporaryList;
+    if (d->hasImageInfoOwnership)
+    {
+        temporaryList = d->currentInfos;
+        d->hasImageInfoOwnership = false;
+    }
+
     d->currentInfos      = infos;
 
     m_dirtyPropertiesTab = false;
@@ -180,11 +207,16 @@
     d->dirtyDesceditTab  = false;
 
     slotChangedTab( getActiveTab() );
+
+    for (ImageInfo *info = temporaryList.first(); info; info = temporaryList.next())
+    {
+        delete info;
+    }
 }
 
 void ImagePropertiesSideBarDB::takeImageInfoOwnership(bool takeOwnership)
 {
-    d->currentInfos.setAutoDelete(takeOwnership);
+    d->hasImageInfoOwnership = takeOwnership;
 }
 
 
Comment 4 Geoff King 2007-01-26 02:14:09 UTC
Seems okay now. Thanks.