Bug 160284

Summary: bad mmap causes cores in KPCMemoryDevice
Product: [Frameworks and Libraries] kdelibs Reporter: Matthew Woehlke <mwoehlke.floss>
Component: kdeuiAssignee: kdelibs bugs <kdelibs-bugs>
Status: RESOLVED FIXED    
Severity: grave CC: erik_hahn, l.lunak, mail, rdieter, rivolaks
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: Make data after header properly aligned.
"backtrace"
The patch
kpixmapcache.cpp
Patch that fixes the crasher for me
Alignment + truncated mmap fixes.

Description Matthew Woehlke 2008-04-03 01:11:56 UTC
Version:            (using Devel)
Installed from:    Compiled sources
Compiler:          gcc (GCC) 4.1.2 
OS:                Linux

I've had about a half dozen cores in nearly as few days involving KPCMemoryDevice, all of which seem to have the same backtrace, and the same problem (memory pointer from mmap is invalid). Here's a backtrace from KWrite:

#0  0xb7956a4e in KPCMemoryDevice (this=0xbf96eb08, start=0xb4c82000 <Address 0xb4c82000 out of bounds>, size=0x807e3a8, available=16240640)                             
    at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:153                                                                                    
#1  0xb7956dcf in KPixmapCache::Private::mmapFile (this=0x807e360, filename=@0x807e374, info=0x807e3a0, newsize=16240640)                                                
    at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:467                                                                                    
#2  0xb79584f3 in KPixmapCache::Private::mmapFiles (this=0x807e360) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:397                    
#3  0xb7957267 in KPixmapCache::recreateCacheFiles (this=0x809c778) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:1159                   
#4  0xb7957833 in KPixmapCache::Private::checkFileVersion (this=0x807e360, filename=@0x807e374) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:682
#5  0xb7957aa6 in KPixmapCache::Private::init (this=0x807e360) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:990                                 
#6  0xb7957c25 in KPixmapCache::discard (this=0x809c778) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:1185                                      
#7  0xb7955412 in KIconCache::Private::checkForThemeUpdates (this=0x80bd938) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kiconcache.cpp:81                      
#8  0xb79536ce in KIconCache::find (this=0x809c778, key=@0xbf96eec4, pix=@0xbf96eec8, path=0x0) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kiconcache.cpp:266  
#9  0xb7946dab in KIconLoader::loadIcon (this=0x80bd4b8, _name=@0x838e3d0, group=KIconLoader::Desktop, size=22, state=0, overlays=@0x838e3d4, path_store=0x0, canReturnNull=false)
    at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kiconloader.cpp:988                                                                                              
#10 0xb7941dc8 in KIconEngine::pixmap (this=0x81b1280, size=@0xbf96fb1c, mode=QIcon::Normal, state=QIcon::Off) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kiconengine.cpp:126
#11 0xb68cdb67 in QIcon::pixmap (this=0xbf970cb0, size=@0xbf96fb1c, mode=QIcon::Normal, state=QIcon::Off) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/image/qicon.cpp:660              
#12 0xb6b13561 in QCommonStyle::drawControl (this=0x80bd648, element=QStyle::CE_ToolButtonLabel, opt=0xbf970c78, p=0xbf971274, widget=0x83d5750)                                               
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/styles/qcommonstyle.cpp:1479                                                                                                           
#13 0xb799964a in KStyle::drawControl (this=0x80bd648, element=QStyle::CE_ToolButtonLabel, option=0xbf970c78, p=0xbf971274, widget=0x83d5750)                                                  
    at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/kernel/kstyle.cpp:2141                                                                                                              
#14 0xb605328e in OxygenStyle::drawControl (this=0x80bd648, element=QStyle::CE_ToolButtonLabel, option=0xbf970c78, p=0xbf971274, widget=0x83d5750)                                             
    at /usr/local/kde/home/src/kde-trunk-svn/kdebase/runtime/kstyles/oxygen/oxygen.cpp:312                                                                                                     
#15 0xb798ee05 in KStyle::drawComplexControl (this=0x80bd648, cc=QStyle::CC_ToolButton, opt=0xbf971214, p=0xbf971274, w=0x83d5750)                                                             
    at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/kernel/kstyle.cpp:2977                                                                                                              
#16 0xb6053375 in OxygenStyle::drawComplexControl (this=0x80bd648, control=QStyle::CC_ToolButton, option=0xbf971214, painter=0xbf971274, widget=0x83d5750)                                     
    at /usr/local/kde/home/src/kde-trunk-svn/kdebase/runtime/kstyles/oxygen/oxygen.cpp:288                                                                                                     
#17 0xb6beecbd in QStylePainter::drawComplexControl (this=0xbf971274, cc=QStyle::CC_ToolButton, opt=@0xbf971214)                                                                               
    at ../../include/QtGui/../../../../../../../src/kde/kde-trunk-svn/qt-copy/src/gui/painting/qstylepainter.h:96                                                                              
#18 0xb6ce4cd5 in QToolButton::paintEvent (this=0x83d5750) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/widgets/qtoolbutton.cpp:537                                                     
#19 0xb687c45b in QWidget::event (this=0x83d5750, event=0xbf971900) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:6988                                                
#20 0xb6be038d in QAbstractButton::event (this=0x83d5750, e=0xbf971900) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/widgets/qabstractbutton.cpp:1078                                   
#21 0xb6ce23f8 in QToolButton::event (this=0x83d5750, e=0xbf971900) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/widgets/qtoolbutton.cpp:1105                                           
#22 0xb681269f in QApplicationPrivate::notify_helper (this=0x8055fc8, receiver=0x83d5750, e=0xbf971900) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3735       
#23 0xb68144f9 in QApplication::notify (this=0xbf9730ec, receiver=0x83d5750, e=0xbf971900) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3702                    
#24 0xb79823a4 in KApplication::notify (this=0xbf9730ec, receiver=0x83d5750, event=0xbf971900) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/kernel/kapplication.cpp:311              
#25 0xb730a5d1 in QCoreApplication::notifyInternal (this=0xbf9730ec, receiver=0x83d5750, event=0xbf971900) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:586
#26 0xb68201b7 in QCoreApplication::sendSpontaneousEvent (receiver=0x83d5750, event=0xbf971900)
    at ../../include/QtCore/../../../../../../../src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.h:218
#27 0xb6889a32 in qt_sendSpontaneousEvent (receiver=0x83d5750, event=0xbf971900) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication_x11.cpp:4698
#28 0xb687ac8c in QWidgetPrivate::drawWidget (this=0x83ba078, pdev=0x80e0d3c, rgn=@0xbf971a8c, offset=@0xbf971ac4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4421
#29 0xb687b554 in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=4, rgn=@0xbf971b50, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4519
#30 0xb687b39d in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=5, rgn=@0xbf971c10, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4509
#31 0xb687b39d in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=7, rgn=@0xbf971cd0, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4509
#32 0xb687b39d in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=9, rgn=@0xbf971d90, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4509
#33 0xb687b39d in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=12, rgn=@0xbf971e50, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4509
#34 0xb687b39d in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=14, rgn=@0xbf971f10, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4509
#35 0xb687b39d in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=19, rgn=@0xbf971fd0, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4509
#36 0xb687b39d in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=20, rgn=@0xbf972090, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4509
#37 0xb687b39d in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=21, rgn=@0xbf972150, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4509
#38 0xb687b39d in QWidgetPrivate::paintSiblingsRecursive (this=0x83d3410, pdev=0x80e0d3c, siblings=@0xbf972234, index=22, rgn=@0xbf97239c, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4509
#39 0xb687b0b0 in QWidgetPrivate::drawWidget (this=0x83d3410, pdev=0x80e0d3c, rgn=@0xbf97239c, offset=@0xbf9723d4, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4462
---Type <return> to continue, or q <return> to quit---
#40 0xb687b554 in QWidgetPrivate::paintSiblingsRecursive (this=0x80e12c0, pdev=0x80e0d3c, siblings=@0xbf972484, index=20, rgn=@0xbf972608, offset=@0x807388c, flags=4, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4519
#41 0xb687b0b0 in QWidgetPrivate::drawWidget (this=0x80e12c0, pdev=0x80e0d3c, rgn=@0xbf972608, offset=@0x807388c, flags=5, sharedPainter=0x8210f40)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4462
#42 0xb6a08fe0 in QWidgetBackingStore::cleanRegion (this=0x8073880, rgn=@0xbf9726d4, widget=0x80e1228, recursiveCopyToScreen=true)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/painting/qbackingstore.cpp:1041
#43 0xb6a09365 in qt_syncBackingStore (widget=0x80e1228) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/painting/qbackingstore.cpp:315
#44 0xb687c9e8 in QWidget::event (this=0x80e1228, event=0x8378580) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:7132
#45 0xb6c6140a in QMainWindow::event (this=0x80e1228, event=0x8378580) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/widgets/qmainwindow.cpp:1252
#46 0xb7a45f47 in KMainWindow::event (this=0x80e1228, ev=0x8378580) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/widgets/kmainwindow.cpp:1028
#47 0xb7a7db8f in KXmlGuiWindow::event (this=0x80e1228, ev=0x8378580) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/xmlgui/kxmlguiwindow.cpp:123
#48 0xb681269f in QApplicationPrivate::notify_helper (this=0x8055fc8, receiver=0x80e1228, e=0x8378580) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3735
#49 0xb68144f9 in QApplication::notify (this=0xbf9730ec, receiver=0x80e1228, e=0x8378580) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3702
#50 0xb79823a4 in KApplication::notify (this=0xbf9730ec, receiver=0x80e1228, event=0x8378580) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/kernel/kapplication.cpp:311
#51 0xb730a5d1 in QCoreApplication::notifyInternal (this=0xbf9730ec, receiver=0x80e1228, event=0x8378580) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:586
#52 0xb730e80b in QCoreApplication::sendEvent (receiver=0x80e1228, event=0x8378580)
    at ../../include/QtCore/../../../../../../../src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.h:215
#53 0xb730ab68 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x804acc0) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:1191
#54 0xb730addb in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:1084
#55 0xb733f9cc in QCoreApplication::sendPostedEvents () at ../../include/QtCore/../../../../../../../src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.h:220
#56 0xb733e885 in postEventSourceDispatch (s=0x8057d60) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qeventdispatcher_glib.cpp:211
#57 0xb64c3f85 in IA__g_main_context_dispatch (context=0x8057cd8) at gmain.c:2045
#58 0xb64c5835 in g_main_context_iterate (context=0x8057cd8, block=1, dispatch=1, self=0x8056300) at gmain.c:2677
#59 0xb64c5c42 in IA__g_main_context_iteration (context=0x8057cd8, may_block=1) at gmain.c:2736
#60 0xb733deca in QEventDispatcherGlib::processEvents (this=0x8055b70, flags=@0xbf972fa8) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qeventdispatcher_glib.cpp:325
#61 0xb68caa88 in QGuiEventDispatcherGlib::processEvents (this=0x8055b70, flags=@0xbf972fdc) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qguieventdispatcher_glib.cpp:204
#62 0xb7306be0 in QEventLoop::processEvents (this=0xbf97305c, flags=@0xbf973014) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qeventloop.cpp:146
#63 0xb7306d8b in QEventLoop::exec (this=0xbf97305c, flags=@0xbf973064) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qeventloop.cpp:197
#64 0xb730aefa in QCoreApplication::exec () at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:838
#65 0xb68123bc in QApplication::exec () at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3267
#66 0xb7f96ea5 in kdemain (argc=2, argv=0xbf9734f4) at /usr/local/kde/home/src/kde-trunk-svn/kdebase/apps/kwrite/kwritemain.cpp:786
#67 0x080487b6 in main (argc=Cannot access memory at address 0x0
) at /usr/local/kde/home/build/kde-trunk-svn/kdebase/apps/kwrite/kwrite_dummy.cpp:3

I also should have at least one of the cores permanently saved for further digging. The file fd looked OK the one time I managed to dig it up.
Comment 1 Matthew Woehlke 2008-04-03 02:28:35 UTC
Ok, this just went from "annoying but tolerable" to "must now give serious consideration to ditching KDE4 until this is fixed".

This looks related (also KPixmapCache, also involving mmap), and is from Konsole. For me, Konsole dying is very nearly as bad as X dying, which is to say it has a *grave* impact on my ability to Work productively. As this affects all KDE applications and can cause data loss, I'm considering upgrading the severity to "grave"... but I won't without a second recommendation, as it seems rather self-serving :-).

Anyway...

#0  0xb7911b5e in KPixmapCache::Private::mmapFile (this=0xbf9e7ea8, filename=@0xb4bf6000, info=0x808aae0, newsize=16240640)                                                                         
    at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:436                                                                                                               
#1  0xb7911edf in KPixmapCache::Private::invalidateMmapFiles (this=0x808aa98) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:424                                     
#2  0xb7913603 in KPixmapCache::Private::dataDevice (this=0x808aa98) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:555                                              
#3  0xb7912ccf in KPixmapCache::size (this=0x808aa98) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:1074                                                            
#4  0xb7912d35 in KPixmapCache::loadFromSvg (this=0x80bc780, filename=@0x80bc77c, size=@0xb710b041) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kpixmapcache.cpp:1401              
#5  0xb7910522 in operator<< <QString> (out=@0x80bc760, set=@0x83f89bc) at /usr/local/kde/qt-copy/include/QtCore/qdatastream.h:328                                                                  
#6  0xb790e7ee in KIconCache::setThemeInfo (this=0x80c5a78, themes=@0xbf9e80e4) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kiconcache.cpp:253                                     
#7  0xb7901f41 in KIconLoader::loadIcon (this=0x80bc310, _name=@0x83f89b8, group=KIconLoader::Desktop, size=16, state=0, overlays=@0x83f89bc, path_store=0x0, canReturnNull=false)                  
    at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kiconloader.cpp:1015                                                                                                               
#8  0xb78fcdc0 in KIconEngine::pixmap (this=0x837d108, size=@0xbf9e8520, mode=QIcon::Normal, state=QIcon::Off) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/icons/kiconengine.cpp:126     
#9  0xb6848b67 in QIcon::pixmap (this=0xbf9e9de4, size=@0xbf9e8520, mode=QIcon::Normal, state=QIcon::Off) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/image/qicon.cpp:660                   
#10 0xb7957d81 in KStyle::drawKStylePrimitive (this=0x80bc488, widgetType=KStyle::WT_TabBar, primitive=65536, opt=0xbf9ec1fc, r=@0xbf9e9dcc, pal=@0xbf9ea0f8, flags=@0xbf9e9a28, p=0xbf9ec384,      
    widget=0x815a490, kOpt=0xbf9e9ddc) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/kernel/kstyle.cpp:581                                                                                 
#11 0xb5fc644d in OxygenStyle::drawKStylePrimitive (this=0x80bc488, widgetType=KStyle::WT_TabBar, primitive=65536, opt=0xbf9ec1fc, r=@0xbf9e9dcc, pal=@0xbf9ea0f8, flags=@0xbf9ea5a8,               
    p=0xbf9ec384, widget=0x815a490, kOpt=0xbf9e9ddc) at /usr/local/kde/home/src/kde-trunk-svn/kdebase/runtime/kstyles/oxygen/oxygen.cpp:1784                                                        
#12 0xb7953e56 in KStyle::drawControl (this=0x80bc488, element=QStyle::CE_TabBarTabLabel, option=0xbf9ec1fc, p=0xbf9ec384, widget=0x815a490)                                                        
    at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/kernel/kstyle.cpp:2067                                                                                                                   
#13 0xb5fc662c in OxygenStyle::drawKStylePrimitive (this=0x80bc488, widgetType=KStyle::WT_Menu, primitive=-1080114692, opt=0xbf9ec384, r=@0x815a490, pal=@0x0, flags=@0x0, p=0x0, widget=0x0,       
    kOpt=0x21) at /usr/local/kde/home/src/kde-trunk-svn/kdebase/runtime/kstyles/oxygen/oxygen.cpp:1795                                                                                              
#14 0xb6a8f23b in QCommonStyle::drawControl (this=0x80bc488, element=QStyle::CE_TabBarTab, opt=0xbf9ec1fc, p=0xbf9ec384, widget=0x815a490)                                                          
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/styles/qcommonstyle.cpp:1580                                                                                                                
#15 0xb79547f2 in KStyle::drawPrimitive (this=0x80bc488, elem=QStyle::PE_FrameDockWidget, option=0xbf9ec1fc, painter=0xbf9ec384, widget=0x815a490)                                                  
    at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/kernel/kstyle.cpp:713                                                                                                                    
#16 0xb5fc662c in OxygenStyle::drawKStylePrimitive (this=0x80bc488, widgetType=KStyle::WT_MenuBar, primitive=-1080114692, opt=0xbf9ec384, r=@0x815a490, pal=@0x0, flags=@0xe4, p=0x22, widget=0x0,  
    kOpt=0x805e2c8) at /usr/local/kde/home/src/kde-trunk-svn/kdebase/runtime/kstyles/oxygen/oxygen.cpp:1795                                                                                         
#17 0xb6b7999d in QStylePainter::drawControl (this=0xbf9ec384, ce=QStyle::CE_TabBarTab, opt=@0xbf9ec1fc)
    at ../../include/QtGui/../../../../../../../src/kde/kde-trunk-svn/qt-copy/src/gui/painting/qstylepainter.h:91
#18 0xb6c413cf in QTabBar::paintEvent (this=0x815a490) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/widgets/qtabbar.cpp:1284
#19 0xb67f745b in QWidget::event (this=0x815a490, event=0xbf9eca70) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:6988
#20 0xb6c3f9e1 in QTabBar::event (this=0x815a490, e=0xbf9eca70) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/widgets/qtabbar.cpp:1204
#21 0xb678d69f in QApplicationPrivate::notify_helper (this=0x805bf40, receiver=0x815a490, e=0xbf9eca70) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3735
#22 0xb678f4f9 in QApplication::notify (this=0xbf9ee018, receiver=0x815a490, e=0xbf9eca70) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3702
#23 0xb793d54c in QEvent::isAccepted (this=0xbf9ee018) at /usr/local/kde/qt-copy/include/QtCore/qcoreevent.h:279
#24 0xb71c35d1 in QCoreApplication::notifyInternal (this=0xbf9ee018, receiver=0x815a490, event=0xbf9eca70) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:586
#25 0xb679b1b7 in QCoreApplication::sendSpontaneousEvent (receiver=0x815a490, event=0xbf9eca70)
    at ../../include/QtCore/../../../../../../../src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.h:218
#26 0xb6804a32 in qt_sendSpontaneousEvent (receiver=0x815a490, event=0xbf9eca70) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication_x11.cpp:4698
#27 0xb67f5c8c in QWidgetPrivate::drawWidget (this=0x8120fd0, pdev=0x807962c, rgn=@0xbf9ecbfc, offset=@0xbf9ecc34, flags=4, sharedPainter=0xab26aa8)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4421
#28 0xb67f6554 in QWidgetPrivate::paintSiblingsRecursive (this=0x81c8918, pdev=0x807962c, siblings=@0xbf9ecce4, index=2, rgn=@0xbf9ece4c, offset=@0xbf9ece84, flags=4, sharedPainter=0xab26aa8)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4519
#29 0xb67f60b0 in QWidgetPrivate::drawWidget (this=0x81c8918, pdev=0x807962c, rgn=@0xbf9ece4c, offset=@0xbf9ece84, flags=4, sharedPainter=0xab26aa8)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4462
#30 0xb67f6554 in QWidgetPrivate::paintSiblingsRecursive (this=0x8107ee0, pdev=0x807962c, siblings=@0xbf9ecf34, index=1, rgn=@0xbf9ed09c, offset=@0xbf9ed0d4, flags=4, sharedPainter=0xab26aa8)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4519
#31 0xb67f60b0 in QWidgetPrivate::drawWidget (this=0x8107ee0, pdev=0x807962c, rgn=@0xbf9ed09c, offset=@0xbf9ed0d4, flags=4, sharedPainter=0xab26aa8)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4462
#32 0xb67f6554 in QWidgetPrivate::paintSiblingsRecursive (this=0x8120828, pdev=0x807962c, siblings=@0xbf9ed184, index=1, rgn=@0xbf9ed2ec, offset=@0xbf9ed324, flags=4, sharedPainter=0xab26aa8)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4519
#33 0xb67f60b0 in QWidgetPrivate::drawWidget (this=0x8120828, pdev=0x807962c, rgn=@0xbf9ed2ec, offset=@0xbf9ed324, flags=4, sharedPainter=0xab26aa8)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4462
#34 0xb67f6554 in QWidgetPrivate::paintSiblingsRecursive (this=0x805b2c0, pdev=0x807962c, siblings=@0xbf9ed3d4, index=10, rgn=@0xbf9ed558, offset=@0x80e2564, flags=4, sharedPainter=0xab26aa8)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4519
#35 0xb67f60b0 in QWidgetPrivate::drawWidget (this=0x805b2c0, pdev=0x807962c, rgn=@0xbf9ed558, offset=@0x80e2564, flags=5, sharedPainter=0xab26aa8)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:4462
#36 0xb6983fe0 in QWidgetBackingStore::cleanRegion (this=0x80e2558, rgn=@0xbf9ed624, widget=0x80eaa40, recursiveCopyToScreen=true)
    at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/painting/qbackingstore.cpp:1041
#37 0xb6984365 in qt_syncBackingStore (widget=0x80eaa40) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/painting/qbackingstore.cpp:315
#38 0xb67f79e8 in QWidget::event (this=0x80eaa40, event=0x95c6700) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qwidget.cpp:7132
---Type <return> to continue, or q <return> to quit---
#39 0xb6bdc40a in QMainWindow::event (this=0x80eaa40, event=0x95c6700) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/widgets/qmainwindow.cpp:1252
#40 0xb7a010cb in ~DockResizeListener (this=0x80eaa40) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/widgets/kmainwindow.cpp:112
#41 0xb7a38d3f in ~KXmlGuiWindow (this=0x80eaa40) at /usr/local/kde/home/src/kde-trunk-svn/kdelibs/kdeui/xmlgui/kxmlguiwindow.cpp:119
#42 0xb678d69f in QApplicationPrivate::notify_helper (this=0x805bf40, receiver=0x80eaa40, e=0x95c6700) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3735
#43 0xb678f4f9 in QApplication::notify (this=0xbf9ee018, receiver=0x80eaa40, e=0x95c6700) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3702
#44 0xb793d54c in QEvent::isAccepted (this=0xbf9ee018) at /usr/local/kde/qt-copy/include/QtCore/qcoreevent.h:279
#45 0xb71c35d1 in QCoreApplication::notifyInternal (this=0xbf9ee018, receiver=0x80eaa40, event=0x95c6700) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:586
#46 0xb71c780b in QCoreApplication::sendEvent (receiver=0x80eaa40, event=0x95c6700)
    at ../../include/QtCore/../../../../../../../src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.h:215
#47 0xb71c3b68 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x804aad8) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:1191
#48 0xb71c3ddb in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:1084
#49 0xb71f89cc in QCoreApplication::sendPostedEvents () at ../../include/QtCore/../../../../../../../src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.h:220
#50 0xb71f7885 in postEventSourceDispatch (s=0x805e2c8) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qeventdispatcher_glib.cpp:211
#51 0xb6436f85 in IA__g_main_context_dispatch (context=0x805e240) at gmain.c:2045
#52 0xb6438835 in g_main_context_iterate (context=0x805e240, block=1, dispatch=1, self=0x805c0a0) at gmain.c:2677
#53 0xb6438c42 in IA__g_main_context_iteration (context=0x805e240, may_block=1) at gmain.c:2736
#54 0xb71f6eca in QEventDispatcherGlib::processEvents (this=0x80564b0, flags=@0xbf9edef8) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qeventdispatcher_glib.cpp:325
#55 0xb6845a88 in QGuiEventDispatcherGlib::processEvents (this=0x80564b0, flags=@0xbf9edf2c) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qguieventdispatcher_glib.cpp:204
#56 0xb71bfbe0 in QEventLoop::processEvents (this=0xbf9edfac, flags=@0xbf9edf64) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qeventloop.cpp:146
#57 0xb71bfd8b in QEventLoop::exec (this=0xbf9edfac, flags=@0xbf9edfb4) at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qeventloop.cpp:197
#58 0xb71c3efa in QCoreApplication::exec () at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/corelib/kernel/qcoreapplication.cpp:838
#59 0xb678d3bc in QApplication::exec () at /usr/local/src/kde/kde-trunk-svn/qt-copy/src/gui/kernel/qapplication.cpp:3267
#60 0xb7fa1bd7 in ZModemDialog (this=0x1, parent=0xbf9ee164, modal=40, caption=@0x8048806) at /usr/local/kde/home/src/kde-trunk-svn/kdebase/apps/konsole/src/ZModemDialog.cpp:37
#61 0x080487c6 in main (argc=Cannot access memory at address 0x0
) at /usr/local/kde/home/build/kde-trunk-svn/kdebase/apps/konsole/src/konsole_dummy.cpp:3
Comment 2 Sebastian Sauer 2008-04-04 00:26:21 UTC
Changed status from crash to grave since there are more components like KWin and Plasma affected in this crash and it may result in an unusable session where only CTRL+SHIFT+BACKSPACE helps.

So, I am able to reproduce this with the Systemsettings=>Appearance=>Icons by switching to another theme though mostly I need to switch 10-20 times till it happens and each time it happens something random like Plasma, Systemsettings or KWin crashes.

The reason is, that at switching the icon-theme it's needed to clear the icon-cache. For this at http://websvn.kde.org/trunk/KDE/kdebase/runtime/kcontrol/icons/iconthemes.cpp?view=markup the KIconCache::deleteCache() is called which works fine but leads to the crash. Even trying to work around this by deleting the cache at http://websvn.kde.org/trunk/KDE/kdelibs/kdeui/icons/kiconloader.cpp?view=markup after/before the "mIconCache = new KIconCache;" doesn't fix this.

What helps 100% is to undef USE_MMAP at http://websvn.kde.org/trunk/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp?view=markup
Comment 3 Sebastian Sauer 2008-04-04 00:32:55 UTC
Added Rivo, who probably knows more about the iconcache internals, to the CC-list.

at Rivo;
My personal feeling and last hours of debugging says, that the RemovalThread may part of the problem, but I am totally unsure there. So, any hint/idea how to track this one down would be great. Thanks in advance :)
Comment 4 Sebastian Sauer 2008-04-04 00:47:55 UTC
at Matthew:
re "since a few days"... may it be possible that this happens since 2008-04-01? There I committed r792708 which does delete the KIconCache on KIconLoader::reconfigure() now while before we lost that memory (but still had a valid KIconCache around). I was expecting potential problems and therefore did test everything related to iconloader/-cache functionality within last days. Though seems I can't reproduce the prob with anything else then systemsettings.
Well, a quick & dirty fix may to just don't delete the iconcache, but take the instance over even after a reconfigure. Through that wouldn't solve the issue if the cache got explicit deleted :-(
Comment 5 Matthew Woehlke 2008-04-04 01:25:30 UTC
> may it be possible that this happens since 2008-04-01

No. I have a core from 2008-03-27 that I remember being this issue, but the backtrace is no longer correct due to having rebuilt qt-copy since (and frequently rebuilding trunk). However, I know I had talked to rivo about the issue at the time, and my IRC log confirms the date as 2008-03-27. It's possible that was the first occurrence, though.

Anyway, nice to hear that it's not just me...

Our "about severity" page lists "grave: loss of data", so the severity is surely justified (it easily causes data loss when taking out something like Konsole); I just didn't want to be whining :-), especially if it turned out to be a problem on my end.
Comment 6 Michael Pyne 2008-05-27 05:11:51 UTC
Created attachment 24962 [details]
Make data after header properly aligned.

A crash was reported on kde-devel due to unaligned memory access to what is
basically a pointer + mSizeEntryOffset.

Any kind of pointer dereference should either be through aligned memory, or you
should handle yourself since some architectures cannot handle unaligned memory
access.  Architectures that can handle will generally receive a significant
speed boost if you ensure all memory accesses are aligned.

The compiler will align data entries in a struct for you unless you tell it not
to so what I tried doing at first was to make the kpc_magic part of a anonymous
struct with the character string inline (but I couldn't get it to work).

Instead this patch adds padding after the magic and version data such that the
header takes up some multiple of sizeof(void*) bytes, which should make the
subsequent data get correct pointer alignment.

I haven't combed through the code to see how many other memory access there
are, but if there are more we may need to fix those too.

Please test this patch, it works for me (and will bump the pixmap cache version
so if you revert this delete your icon cache) but x86 does not experience
crashes due to alignment in general so I'm not sure if this is sufficient.
Comment 7 Sebastian Sauer 2008-05-28 02:44:03 UTC
Thank you very much for the patch and the detailed explanation.

So, first I did recompiled everything and did test that the at comment #2 described bug is still present for me. Most time kwin is crashing what let's the window-decoration disappear while plasma and running apps are still there.

Then I applied the patch, recompiled and now it's not any longer kwin which crashes but the whole kde-session and what stays is a blank x.org.

I am btw on a amd64 dual-core, 2.6.24.7, nvidia and did rm the cache, KDEHOME, etc. between the tests and will try to continue testing next days (may take a bit time cause of linuxtag and other things ;) to provide some more details.

But that for sure doesn't mean, that we have here multiple reasons for the crash where the patch may fix one of them. So, would be nice if others who are able to reproduce it, could test too.
Comment 8 Sebastian Sauer 2008-05-28 02:47:17 UTC
and the thread that reports on kde-devel a crash due to unaligned memory access is (for archival purpose) at: http://lists.kde.org/?t=121168403800002&r=1&w=2
Comment 9 Michael Pyne 2008-05-28 03:30:52 UTC
Sebastian, thanks for testing.  I'll stand by for backtraces or other troubleshooting data. ;)

What I had to do after wedging KDE while testing the patch was use Fluxbox instead and then open KDE applications from an xterm to make it easy to debug without bringing down everything around me.
Comment 10 Rivo Laks 2008-05-28 11:53:40 UTC
Michael, thanks for the fix!

Unfortunately I haven't had any time to look at the problem myself (nor to do any other KDE-related work, I'm very busy with school ATM), but I'm thinking it might be some kind of a race/locking issue. Most methods use the lockfile to ensure that there's only one KPC object accessing the data, but there might be some that aren't yet should be.
I'll still be busy for the next two weeks but after that I'll look into the problem and make some kind of a fix before the 4.1 final.

And I had a quick look through the code to check if there might be some other alignment issues. I didn't find any (although I might of course have missed it).
Comment 11 Sebastian Sauer 2008-05-29 02:13:56 UTC
Created attachment 24987 [details]
"backtrace"

Unfortunately the prob is only reproducable for me within a full KDE-session
else it would be much easier to catch a backtrace (especially since I still use
KDE3 for KDE4-developing anyway ;)

Well, what I did was to create my own "backtrace" routine. This attached file
is the backtrace itself. Read it bottom-up. It seems to be the case that in all
my tests the crash happens on KPixmapCache::insert().
Comment 12 Sebastian Sauer 2008-05-29 02:17:40 UTC
Created attachment 24988 [details]
The patch

and this is the patch against kdelibs/ui I used to produce the backtrace above
which may needed to have matching line-numbers. The patch from comment #6 was
already applied.

I'll continue tomorrow evening to investigate it more detailed :)
Comment 13 Sebastian Sauer 2008-05-29 23:01:38 UTC
uff. Took a while and I had to change my environment but finally I was able to catch a real backtrace;

Program received signal SIGBUS, Bus error.
[Switching to Thread 0x2addc614e400 (LWP 14486)]
0x00002addc37acd25 in memcpy () from /lib/libc.so.6
(gdb) bt
#0  0x00002addc37acd25 in memcpy () from /lib/libc.so.6
#1  0x00002addc1f6b845 in KPCMemoryDevice (this=0x7fffed596e10, start=0x2aaaaba24000 "KDE PIXMAP CACHE ",
    size=0x71c200, available=16240640) at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:173
#2  0x00002addc1f6c261 in KPixmapCache::Private::mmapFile (this=0x71c190, filename=@0x71c1b0,
    info=0x71c1f0, newsize=16240640) at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:523
#3  0x00002addc1f70939 in KPixmapCache::Private::mmapFiles (this=0x71c190)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:442
#4  0x00002addc1f6ee05 in KPixmapCache::Private::init (this=0x71c190)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:1107
#5  0x00002addc1f6f014 in KPixmapCache::ensureInited (this=0x71c270)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:1116
#6  0x00002addc1f7055b in KPixmapCache::isValid (this=0x71c270)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:1137
#7  0x00002addc1f5bfcd in KIconLoaderPrivate::init (this=0x83d880, _appname=@0x7fffed5973b0, _dirs=0x61cd10)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kiconloader.cpp:399
#8  0x00002addc1f5c360 in KIconLoader::reconfigure (this=0x68a960, _appname=@0x7fffed5973b0, _dirs=0x61cd10)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kiconloader.cpp:379
#9  0x00002addc1f5c623 in KIconLoader::newIconLoader (this=0x68a960)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kiconloader.cpp:1610
#10 0x00002addc1f5c686 in KIconLoader::qt_metacall (this=0x68a960, _c=QMetaObject::InvokeMetaMethod, _id=0,
    _a=0x7fffed597550) at /home/kde4/svn/_build/kdelibs/kdeui/kiconloader.moc:65
#11 0x00002addbfa164a7 in QMetaObject::activate (sender=0x65a400, from_signal_index=10, to_signal_index=10,
    argv=0x7fffed597550) at kernel/qobject.cpp:2998
#12 0x00002addbfa1690b in QMetaObject::activate (sender=0x65a400, m=0x2addc2398a20, local_signal_index=6,
    argv=0x7fffed597550) at kernel/qobject.cpp:3071
#13 0x00002addc1fc79a4 in KGlobalSettings::iconChanged (this=0x65a400, _t1=3)
    at /home/kde4/svn/_build/kdelibs/kdeui/kglobalsettings.moc:140
#14 0x00002addc1fca1ef in KGlobalSettings::Private::_k_slotNotifyChange (this=0x652120, changeType=4, arg=3)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/kernel/kglobalsettings.cpp:833
#15 0x00002addc1fca3bc in KGlobalSettings::qt_metacall (this=0x65a400, _c=QMetaObject::InvokeMetaMethod,
    _id=9, _a=0x7fffed5977e0) at /home/kde4/svn/_build/kdelibs/kdeui/kglobalsettings.moc:91
#16 0x00002addc025f199 in QDBusConnectionPrivate::deliverCall (this=0x67c200, object=0x65a400,
    msg=@0x752938, metaTypes=@0x752940, slotIdx=13) at qdbusintegrator.cpp:865
#17 0x00002addc02691c7 in QDBusCallDeliveryEvent::placeMetaCall (this=0x7528f0, object=0x65a400)
    at qdbusintegrator_p.h:136
#18 0x00002addbfa14801 in QObject::event (this=0x65a400, e=0x7528f0) at kernel/qobject.cpp:1128
#19 0x00002addc0cce62b in QApplicationPrivate::notify_helper (this=0x61d040, receiver=0x65a400, e=0x7528f0)
    at kernel/qapplication.cpp:3772
#20 0x00002addc0cce93a in QApplication::notify (this=0x7fffed5984e0, receiver=0x65a400, e=0x7528f0)
    at kernel/qapplication.cpp:3366
#21 0x00002addc1f9ee40 in KApplication::notify (this=0x7fffed5984e0, receiver=0x65a400, event=0x7528f0)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/kernel/kapplication.cpp:311
#22 0x00002addbd774df3 in KWin::Application::notify (this=0x7fffed5984e0, o=0x65a400, e=0x7528f0)
    at /home/kde4/svn/_src/KDE/kdebase/workspace/kwin/main.cpp:368
#23 0x00002addbfa01a62 in QCoreApplication::notifyInternal (this=0x7fffed5984e0, receiver=0x65a400,
    event=0x7528f0) at kernel/qcoreapplication.cpp:583
Comment 14 Sebastian Sauer 2008-05-29 23:14:04 UTC
Created attachment 25001 [details]
kpixmapcache.cpp

and since my kpixmapcache.cpp was locally modified and the line-numbers don't
match to those from trunk, I just attach my kpixmapcache.cpp :)

#173: memcpy(buf, mMemory + mSizeEntryOffset, 4);
#523: KPCMemoryDevice dev(info->memory, &info->size, info->available);
#442: if (!mmapFile(mDataFile, &mDataMmapInfo, (int)(q->cacheLimit() * 1.5 +
500) * 1024)) {
Comment 15 Michael Pyne 2008-05-29 23:49:40 UTC
Sebastian:  It is an alignment error still.  Assuming mMemory points to a valid address, that means mSizeEntryOffset on line 173 makes an unaligned address.

This comes from the kpc_header_len variable which I changed to make aligned (or so I thought).  I believe the calculation is right but to be sure it would be helpful to figure out what kpc_header_len is on your system.

What you can do is in the calculation of padding length required (on line 408 of your modified file), change sizeof(void*) in all 3 spots to be 8 (you may have to all bump the pixmap version).  Retest.

If 8 does not work, try 16.  The final kpc_header_len should always be a multiple of the number you try (so probably a multiple of 4 or 8 right now, when you change to 16 it should be a multiple of 16).

If the calculation is right then I need a better way to determine alignment at compile time, although I can hardcode 16 for now if necessary.
Comment 16 Sebastian Sauer 2008-05-30 00:37:27 UTC
kpc_header_len and mSizeEntryOffset where 24.
s/sizeof(void*)/8 => 24 again
s/sizeof(void*)/16 => 32

It still crashes, but I wasn't able to catch a useful backtrace yet since it seems gdb continues to run into http://osdir.com/ml/gdb.bugs.discuss/2007-11/msg00036.html - grrrr, if one bug hits another :-/

I'll continue to investigate next days.
Comment 17 Sebastian Sauer 2008-05-30 01:04:44 UTC
ok, backtrace catched but this time it took quit a very long time till it was crashing.

Changes I did;
* changed sizeof(void*) to 16 at the 3 places
* undef the "#define NO_LAZYLOAD_ICONTHEME" in kiconloader.cpp
* added info->size=0; at the delete info->file's (happens also without this change)
* and for sure the usual kill session && restart dbus && find . -name "*icon*cache*" -exec rm {} \; && recompile && start session && attach gdb's

#0  0x00002afe6a9d2d25 in memcpy () from /lib64/libc.so.6
#1  0x00002afe65247f71 in KPCMemoryDevice (this=0x7fff4802acb0, start=0x2aaaadcb6000 "KDE PIXMAP CACHE ",
    size=0x87cf70, available=16240640) at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:153
#2  0x00002afe65248362 in KPixmapCache::Private::mmapFile (this=0x87cf00, filename=@0x87cf20,
    info=0x87cf60, newsize=16240640) at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:483
#3  0x00002afe652499f2 in KPixmapCache::Private::mmapFiles (this=0x87cf00)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:410
#4  0x00002afe65248941 in KPixmapCache::recreateCacheFiles (this=0x66f880)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kpixmapcache.cpp:1182
#5  0x00002afe652457e1 in KIconCache::setThemeInfo (this=0x66f880, themes=@0x7fff4802afc0)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kiconcache.cpp:262
#6  0x00002afe6523c0d8 in KIconLoaderPrivate::init (this=0x71bae0, _appname=@0x7fff4802b0b0, _dirs=0x66ba20)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kiconloader.cpp:405
#7  0x00002afe6523c36c in KIconLoader::reconfigure (this=0x670c30, _appname=@0x7fff4802b0b0, _dirs=0x66ba20)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kiconloader.cpp:379
#8  0x00002afe6523c62f in KIconLoader::newIconLoader (this=0x670c30)
    at /home/kde4/svn/_src/KDE/kdelibs/kdeui/icons/kiconloader.cpp:1610
#9  0x00002afe6523c692 in KIconLoader::qt_metacall (this=0x670c30, _c=QMetaObject::InvokeMetaMethod, _id=0,
    _a=0x7fff4802b250) at /home/kde4/svn/_build/kdelibs/kdeui/kiconloader.moc:65
#10 0x00002afe6858f4a7 in QMetaObject::activate (sender=0x6a0080, from_signal_index=10, to_signal_index=10,
    argv=0x7fff4802b250) at kernel/qobject.cpp:2998
#11 0x00002afe6858f90b in QMetaObject::activate (sender=0x6a0080, m=0x2afe6566c5a0, local_signal_index=6,
    argv=0x7fff4802b250) at kernel/qobject.cpp:3071
#12 0x00002afe6529b918 in KGlobalSettings::iconChanged (this=0x6a0080, _t1=0)
    at /home/kde4/svn/_build/kdelibs/kdeui/kglobalsettings.moc:140
Comment 18 Sebastian Sauer 2008-05-30 01:14:35 UTC
hmmmm.... see

void KPixmapCache::deleteCache(const QString& name)

it does just QFile::remove while MmapInfo::file still points to the mmap'd file. Probably that's the reason?
Comment 19 Michael Pyne 2008-05-30 01:25:07 UTC
Sebastian: What platform are you using?  I believe you're probably right because Wikipedia says this about possible reasons to get SIGBUS (besides alignment):

BUS_OBJERROR (info from the SIGBUS signal) is a far less common signal but it is present in Solaris, when virtual memory pages have disappeared (e.g. accessing an mmap()'ed file which has been truncated).  This matches the description of the problem exactly.
Comment 20 Matthew Woehlke 2008-05-30 02:20:18 UTC
> virtual memory pages have disappeared

That might be what I'm seeing. I'm a bit baffled how we got a Solaris alignment bug in here, when it seems to be a separate issue (I'm on x86, I shouldn't be getting alignment errors :-)). But I'm glad this is being looked at.

I wonder why there don't seem to be more reports of this, maybe distros are doing what I did and working around it with the sledgehammer of disabling mmap?
Comment 21 Michael Pyne 2008-05-30 03:12:25 UTC
Matthew: The man pages I have for mmap(2) indicate that Linux is more than happy to throw SIGBUS if the underlying file has been deleted/truncated.

I think Rivo is right and that it's some kind of race condition, only I don't think it's due to threading, but instead due to reentrancy (different processes playing with the pixmap cache).
Comment 22 Michael Pyne 2008-05-30 04:06:09 UTC
KPixmapCache::deleteCache(name) is static, and can therefore be called at any time.  So, the KPixmapCache code needs to be able to handle SIGBUS at basically any time in case the cache gets deleted out from under code that has the cache mmap()'ed.

What we can (try) to do in the interim is to ensure that all code calling deleteCache() is only called in situations where the cache is not mmap()'ed.

I noticed that mmap support can be disabled.  Is this an enormous slowdown if disabled or can we disable it by default until this is more ironclad?
Comment 23 Rivo Laks 2008-05-30 15:30:55 UTC
With mmap disabled, you'll probably get extra file open+close operation whenever the cache is accessed. But it shouldn't be that slow, I remember using the cache was faster than not using cache even before I implemented the mmap support. So I think you can disable it safely until the problem gets sorted out.

deleteCache() might indeed be causing problems, it should probably do something like KPixmapCachePrivate::invalidateMmapFiles() to make all KPixmapCache objects re-mmap the files. The problem is that deleteCache() is static and therefore doesn't have the mmapped memory. Maybe it could temporarily mmap it, just to invalidate it?

It might also be worth it to check in KPixmapCache::Private::dataDevice() if the data file exists before opening KPCMemoryDevice on it (as the latter accesses the mmapped memory which could be invalid if the file has been deleted). Private::indexDevice already does that.
Comment 24 Matthew Woehlke 2008-05-30 18:22:55 UTC
> The man pages I have for mmap(2) indicate that Linux is more than happy to throw SIGBUS if the underlying file has been deleted/truncated.

Cool, even more likely then someone found the problem I was getting bit by. But there was plenty of stuff before that was talking about "alignment" :-).

A race seems possible, but what I seem to recall from walking the code is that the point of failure is just a few lines after the actual call to mmap, so I'm a bit more dubious that it's a reentrancy thing. But then, I haven't looked at the code in some time...

> I noticed that mmap support can be disabled.  Is this an enormous slowdown if disabled or can we disable it by default until this is more ironclad?

I'd be in favor of that, especially if you do it the same way I did, if only because it'll merge with my local change such that when it's decided to re-enable it, that will magically happen for me :-).
Comment 25 Sebastian Sauer 2008-06-01 02:25:14 UTC
Created attachment 25030 [details]
Patch that fixes the crasher for me

Patch that incoperates the patch from comment #6 and changes
KPixmapCache::deleteCache() and KPixmapCache::discard() to
invalidate+unmmap+remove the cache.

Seems to work for me but needs more testing.
Comment 26 Michael Pyne 2008-06-01 05:05:40 UTC
Sebastian: Does this remove a cache that is not in use by the program (since it now looks by looping over the static mCaches)?  Such behavior is not specified explicitly in the API but I think it would be useful to be able to remove a cache without having to first open it.

I imagine this would also not fix the case where a file was deleted from under an open mmap, such as by a different process calling removeCache().  One way or the other we will have to handle SIGBUS, which is something I will try to work on.
Comment 27 Michael Pyne 2008-06-01 05:13:27 UTC
SVN commit 815057 by mpyne:

Disable the on disk pixmap cache (affects icon caching) as this causes crashes for some use cases, as
discussed on bug 160284.  There are two known causes:

1. Alignment of mmap()'ed data is off, which on some architectures results in a SIGBUS.
2. We can also receive SIGBUS for trying to access mmap()'ed pages where the underlying file has been
   truncated, which has also been an issue.

I'm working on making the code properly handle the SIGBUS signal which we can receive if our mmap()'ed
cache is deleted from under us.  I will also fix a separate issue with alignment of the mmap()'ed data if
I can fix the SIGBUS issue.

CCBUG:160284


 M  +2 -1      kpixmapcache.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=815057
Comment 28 Michael Pyne 2008-06-01 08:08:46 UTC
I've constructed a couple of test cases to explore the behavior of mmap.  I can reliably reproduce SIGBUS if I truncate the shared file.  However, if I do nothing but unlink the shared file then everything continues as normal.

So, I think that the source of the problem may be the info->file->resize() call in ::invalidateMmapFiles().  If the new size is less than the old size we have effectively truncated the file and any shared memory accesses in that last part of the file should crash with SIGBUS.

Sebastian, do you still get crashes if you apply my alignment fix patch but not your changes to cache deletion, but in addition change line 459 from:

if (!info->file->resize(info->available)) {

to
if (info->file->size() < newsize && !info->file->resize(info->available)) {

Note that you will have to uncomment the #define USE_MMAP near the top if you are using the latest kdelibs.

We may of course still have to fix cache deletion.  If you continue to get crashes we could possibly use POSIX shm (shm_open and shm_unlink) which explicitly requires that shared memory last after an unlink until all processes have unmapped the memory regions.

Either way it looks like we may not have to handle SIGBUS as a matter of course after all which is reassuring, especially as there's not too many alternatives.  (SysV IPC is absolutely not an alternative...)I've constructed a couple of test cases to explore the behavior of mmap.  I can reliably reproduce SIGBUS if I truncate the shared file.  However, if I do nothing but unlink the shared file then everything continues as normal.

So, I think that the source of the problem may be the info->file->resize() call in ::invalidateMmapFiles().  If the new size is less than the old size we have effectively truncated the file and any shared memory accesses in that last part of the file should crash with SIGBUS.

Sebastian, do you still get crashes if you apply my alignment fix patch but not your changes to cache deletion, but in addition change line 459 from:

if (!info->file->resize(info->available)) {

to
if (info->file->size() < newsize && !info->file->resize(info->available)) {

Note that you will have to uncomment the #define USE_MMAP near the top if you are using the latest kdelibs.

We may of course still have to fix cache deletion.  If you continue to get crashes we could possibly use POSIX shm (shm_open and shm_unlink) which explicitly requires that shared memory last after an unlink until all processes have unmapped the memory regions.

Either way it looks like we may not have to handle SIGBUS as a matter of course after all which is reassuring, especially as there's not too many alternatives.  (SysV IPC is absolutely not an alternative...)
Comment 29 Sebastian Sauer 2008-06-01 21:31:47 UTC
> Sebastian, do you still get crashes if you apply my alignment fix patch but not your changes to cache deletion, but in addition

yes, still crashes.
Comment 30 Michael Pyne 2008-06-01 22:23:19 UTC
I guess we'll fix all those little things then. :-/
Comment 31 Michael Pyne 2008-06-02 06:25:47 UTC
Created attachment 25062 [details]
Alignment + truncated mmap fixes.

Well the good news is that I was able to use Sebastian's method to reproduce
the bug finally.  The bad news is that just using his patch wasn't enough to
stop SIGBUS on my system, although I suspect that could be related to changes I
had locally trying to fix the bug.

However, a little tweaking of his patch for force unmapping the files before
recreating the cache seems to work fine for me.

The other changes I was talking about is to use real structs to ensure that the
alignment is correct (i.e. have gcc do the work, it knows what to do).	In
addition is gets rid of having to have the size entry offset in KPCMemoryDevice
since it can instead just access the mmap'ed memory directly.

With this patch applied I get no crashers.

One catch is how to change the code such that if you were to do something silly
like start opening applications right after reinstalling the fixed kdelibs,
while all your running applications are still going, how do you avoid causing
crashes?  You can't simply bump the version number this time since it's
probably not the exact same spot it was before.  So what I did was change the
magic string slightly (described in the code).

Sebastian, Matthew, could you test the patch and let me know if you still get
crashes so I can commit this tomorrow (assuming it works)?  Thanks.
Comment 32 Matthew Woehlke 2008-06-02 18:08:19 UTC
> I can reliably reproduce SIGBUS if I truncate the shared file.  However, if I do nothing but unlink the shared file then everything continues as normal.

That's not surprising; in fact now that you mention it, it makes sense that a truncate could hose an otherwise valid mmap. I would have expected unlinking to be safe, but it's not clear if mmap preserves a handle (but it should be safe as long as you don't call close() on the fd until you've munmap'd everything, since on UNIX-y systems an unlinked file isn't gone until all handles are closed).
Comment 33 Sebastian Sauer 2008-06-02 19:21:32 UTC
With the patch from comment #31 the crash is fixed for me.
Comment 34 Matthew Woehlke 2008-06-02 19:57:08 UTC
I probably will not be able to test today. Michael, if you're impatient and both you and Sebastian are confident the patch is good, I'd say go ahead and commit it; I'll certainly let you know if I experience crashes in the future.
Comment 35 Michael Pyne 2008-06-02 23:11:50 UTC
SVN commit 815947 by mpyne:

Re-enable mmap'ed pixmap caches.  Sebastian Sauer and I have been troubleshooting this bug (bug 160284).
This patch does the following, which seems to solve all the SIGBUS issues that we could reproduce:

* Unmap the file before recreating the cache in addition to just invalidating it.
* Make the in memory data structure properly aligned for memory accesses.  I did this by making a struct for
  the header information instead of casting a magic address in order to decode information.  This change
  makes the on-disk layout binary incompatible, so I bumped the pixmap cache version.  Older kdelibs
  versions will not read the version from the same byte so in case of a mix of kdelibs versions (if you
  update a running instance for example) I changed the magic character string to fool older kdelibs into
  seeing it as a newer version.  Doing all this work made my earlier attempts to ensure alignment unneeded.
* The deleteCache() is static, so a list is made of all KPixmapCache::Private classes in the process so they
  can cleanly unmap before deleting the cache.
* Resizing of the mmap'ed files is only done if such resizing would make the file bigger.

Although I forgot to disable mmap()ed caches in 4.0 branch I'll go ahead and backport this in case we
do a 4.0.6.

CCBUG:160284


 M  +1 -1      kiconcache.cpp  
 M  +253 -158  kpixmapcache.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=815947
Comment 36 Michael Pyne 2008-06-02 23:17:19 UTC
SVN commit 815951 by mpyne:

Backport fixes for bug 160284 (mmap/alignment crashes) to 4.0 branch.

BUG:160284


 M  +1 -1      kiconcache.cpp  
 M  +252 -156  kpixmapcache.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=815951
Comment 37 Sebastian Sauer 2008-06-03 19:43:09 UTC
*** Bug 162621 has been marked as a duplicate of this bug. ***
Comment 38 Lubos Lunak 2008-06-04 12:00:20 UTC
I may be missing some technical details, but the "fix" with not resizing the file if it would become smaller looks to me just like a workaround. One is not supposed to get SIGBUS with properly handled mmap files. Either updating the file is done using unlink+create new file, in which case the old file doesn't change and therefore there is no problem, or the file is updated only when properly locked, and then again there cannot be invalid accesses. If the code was getting SIGBUS because of changed file size, then the code is broken, and may possibly break under strange circumstances again.
Comment 39 Michael Pyne 2008-06-05 00:01:53 UTC
Well resizing the file was not the fix at all.  Sebastian had already tried that and continued to receive crashes.  It probably could have been left out but once the last piece I added (which was unmapping the file after invalidating IIRC) worked I didn't want to go and back the resizing check out and I haven't put enough thought into correctly unmapping and remapping the file when a resize is needed.
Comment 40 Sebastian Sauer 2008-06-05 02:40:18 UTC
The whole prob is;

* we may have multiple iconcache-instances around in different processes where each of them may open+mmap the cachefile.
* if one of them now needs to resize the cachefile (e.g. cause the cache should be deleted/truncated), then this may affect the other instances.
* that means, the other instances still have the cachefile open+mmap'ed and keep informations about size, etc. during there lifetime while one of them needs to do something with those cachefile and effectively resizes/deletes and remmap's the file. Those iconcache-instance (+ with my patch also all other instances within the same process) is valid while all other instances are dealing now with invalid mem.

Now the reason why I would agree with Lubos;

Does unmmap+delete file+create file+mmap change the pointer-pos where the mmap'ed cache starts? If yes, then we still have the prob that caches within other processes may deal with mem that was released already. I don't know here about Linux, but at least OpenBSD does return another address on each mmap (see http://kerneltrap.org/node/5584).

So, imho (and after last days of thinking) the bug is not really fixed yet :-/
Comment 41 Sebastian Sauer 2008-06-05 02:43:36 UTC
p.s. with a recent OpenBSD-installation that includes those Memory Allocation patches it should be pretty easy to run from one crash into another the whole time.
Comment 42 Michael Pyne 2008-06-05 04:28:37 UTC
Sebastian, by the way I'm reading the code the resize should happen before the file is mmaped.  The only reason the size should be different is if the file has never been opened, it will be marked with a size of size of 0.  The cache size passed into mmapFile() will be much higher (but constant!) and so this should only get called once.  Which really is another reason the change didn't need to go in I guess.

However if non-KIconCache users of KPixmapCache resize the cache it possible the file size would change (and in fact, maybe the way I did it is a bug..., what if users want to shrink cache size?).  But I think the code will have already unmapped the file by this point if it's being called from resizeCache.  If not that's a separate bug.

Of course another bug is that QDataStream is not versioned but this one isn't a big deal I don't think.
Comment 43 Sebastian Sauer 2008-06-06 06:24:28 UTC
hmmm... so, what to do now? means, anything I can test/do here to help to get right of this report once and forever before we start to buffer-overflow the qint8 that is probably used to number the comments ;)
Comment 44 Michael Pyne 2008-06-06 22:17:43 UTC
Sebastian, I think that strictly speaking that remaining bugs in KPixmapCache are not related to this one anyways.

As far as where to go from here, I would say we need to have a reliable mechanism to force all KPixmapCaches in all processes to unmap shared memory if the size of the underlying file will be changed since we don't handle this case yet.  I think a QWaitCondition fits the bill but I need to figure out how to make this transparent to the application (or maybe Qt 4 has already made this easy, I haven't dealt much with threads)

The cache resize exposed to public API through KPixmapCache::setCacheLimt() so we do need to fix it at some point.  We could then use the same mechanism for when the cache is supposed to be deleted.  The mmap(2) man page says it opens another reference to the fd so I take that to mean that the inode itself is safe if the file is unlinked.

I think I will open a separate bug to deal with the KPixmapCache::setCacheLimit() issue so let's leave this one alone unless we start getting SIGBUS'es due to KPixmapCache again.
Comment 45 Sebastian Sauer 2008-06-07 17:04:20 UTC
remaining issues are handled at bug #163398