Bug 93675

Summary: KMail crashes everytime I close it.
Product: [Unmaintained] kmail Reporter: Thomas Zander <zander>
Component: generalAssignee: kdepim bugs <kdepim-bugs>
Status: RESOLVED FIXED    
Severity: crash CC: simonandric5
Priority: NOR    
Version: 1.7.50   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Valgrind output as requested in #1
kmime_use_staticdeleter.diff

Description Thomas Zander 2004-11-21 18:51:01 UTC
Version:           1.7.50 (using KDE 3.3.89 (CVS >= 20041104), compiled sources)
Compiler:          gcc version 3.3.4 (Debian)
OS:                Linux (i686) release 2.4.21

As soon as I did something 'usefull' (viewed at least one email) my kmail crashes.

See backtrace:
Using host libthread_db library "/lib/libthread_db.so.1".
[Thread debugging using libthread_db enabled]
[New Thread 16384 (LWP 1800)]
[KCrash handler]
#5  0x00000028 in ?? ()
#6  0x420cdc78 in QMutex::~QMutex () from /usr/local/kde/qt/lib/libqt-mt.so.3
#7  0x40b7a726 in __tcf_1 ()
    at /home/zander/sources/kde/kdepim/libkmime/kmime_codecs.cpp:54
#8  0x425f0d41 in __cxa_finalize () from /lib/libc.so.6
#9  0x40b74b20 in __do_global_dtors_aux ()
   from /usr/local/kde/lib/libkmime.so.2
#10 0x40b9bc56 in _fini () from /usr/local/kde/lib/libkmime.so.2
#11 0x4000c4f6 in _dl_init () from /lib/ld-linux.so.2
#12 0x425f0ac2 in exit () from /lib/libc.so.6
#13 0x425dadce in __libc_start_main () from /lib/libc.so.6
#14 0x0804a6b1 in _start () at ../sysdeps/i386/elf/start.S:102
Comment 1 David Faure 2004-11-21 21:23:38 UTC
>     at /home/zander/sources/kde/kdepim/libkmime/kmime_codecs.cpp:54

Looks like a miscompilation to me.
After a clean recompile of kdepim/libkmime, can you try with valgrind if it still happens?

valgrind --tool=memcheck --num-callers=50 kmail --nofork 2>&1 | tee log

Comment 2 Thomas Zander 2004-11-21 22:28:34 UTC
Created attachment 8361 [details]
Valgrind output as requested in #1

I figured something like this when it first happened a week ago (when I moved
from BRANCH to HEAD), so I did a clean compile of the whole kdepim this
morning.  But it still crashed.
So, here is the requested output.  Note that at line 270 I wrote some comments.
Basically everything before is starting, and everything after is quitting.
Comment 3 Matt Douhan 2004-11-21 22:41:17 UTC
I had this too, it stopped with HEAD as of today though
Comment 4 David Faure 2004-11-21 23:12:41 UTC
> Created an attachment (id=8361)
>  --> (http://bugs.kde.org/attachment.cgi?id=8361&action=view)
> Valgrind output as requested in #1

OK, this does look like a bug in the code indeed.

kmime_codecs.cpp:QMutex Codec::dictLock;
kmime_codecs.h:  static QMutex dictLock;

Marc: no static object in libraries!
Solution: KStaticDeleter. Patch attached. I found another static object (the QAsciiDict)
so I changed that one for consistency (not strictly necessary as long as Codec classes
don't have Qt members, but this might change any time...).



Created an attachment (id=8362)
kmime_use_staticdeleter.diff
Comment 5 Till Adam 2005-01-07 00:56:25 UTC
CVS commit by tilladam: 

Patch by David Faure introducing a static deleter to fix crashes on exit.

BUG: 93675


  M +23 -16    kmime_codecs.cpp   1.20
  M +2 -2      kmime_codecs.h   1.19


--- kdepim/libkmime/kmime_codecs.cpp  #1.19:1.20
@@ -41,4 +41,5 @@
 
 #include <qcstring.h>
+#include <kstaticdeleter.h>
 
 #include <cassert>
@@ -50,22 +51,24 @@ namespace KMime {
 
 // global list of KMime::Codec's
-QAsciiDict<Codec> Codec::all( 11, false /* case-insensitive */);
+QAsciiDict<Codec>* Codec::all = 0;
+static KStaticDeleter<QAsciiDict<Codec> > sdAll;
 #if defined(QT_THREAD_SUPPORT)
-QMutex Codec::dictLock;
+QMutex* Codec::dictLock = 0;
+static KStaticDeleter<QMutex> sdDictLock;
 #endif
 
 void Codec::fillDictionary() {
 
-  all.setAutoDelete(true);
+  all->setAutoDelete(true);
 
-  //all.insert( "7bit", new SevenBitCodec() );
-  //all.insert( "8bit", new EightBitCodec() );
-  all.insert( "base64", new Base64Codec() );
-  all.insert( "quoted-printable", new QuotedPrintableCodec() );
-  all.insert( "b", new Rfc2047BEncodingCodec() );
-  all.insert( "q", new Rfc2047QEncodingCodec() );
-  all.insert( "x-kmime-rfc2231", new Rfc2231EncodingCodec() );
-  all.insert( "x-uuencode", new UUCodec() );
-  //all.insert( "binary", new BinaryCodec() );
+  //all->insert( "7bit", new SevenBitCodec() );
+  //all->insert( "8bit", new EightBitCodec() );
+  all->insert( "base64", new Base64Codec() );
+  all->insert( "quoted-printable", new QuotedPrintableCodec() );
+  all->insert( "b", new Rfc2047BEncodingCodec() );
+  all->insert( "q", new Rfc2047QEncodingCodec() );
+  all->insert( "x-kmime-rfc2231", new Rfc2231EncodingCodec() );
+  all->insert( "x-uuencode", new UUCodec() );
+  //all->insert( "binary", new BinaryCodec() );
 
 }
@@ -73,11 +76,15 @@ void Codec::fillDictionary() {
 Codec * Codec::codecForName( const char * name ) {
 #if defined(QT_THREAD_SUPPORT)
-  dictLock.lock(); // protect "all"
+  if ( !dictLock )
+    sdDictLock.setObject( dictLock, new QMutex );
+  dictLock->lock(); // protect "all"
 #endif
-  if ( all.isEmpty() )
+  if ( !all ) {
+    sdAll.setObject( all, new QAsciiDict<Codec>( 11, false /* case-insensitive */) );
     fillDictionary();
-  Codec * codec = all[ name ];
+  }
+  Codec * codec = (*all)[ name ];
 #if defined(QT_THREAD_SUPPORT)
-  dictLock.unlock();
+  dictLock->unlock();
 #endif
 

--- kdepim/libkmime/kmime_codecs.h  #1.18:1.19
@@ -57,7 +57,7 @@ class Codec {
 protected:
 
-  static QAsciiDict<Codec> all;
+  static QAsciiDict<Codec>* all;
 #if defined(QT_THREAD_SUPPORT)
-  static QMutex dictLock;
+  static QMutex* dictLock;
 #endif