[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: Konqueror segfaults
From:       Till Krech <till () snafu ! de>
Date:       2002-10-06 19:20:07
[Download RAW message or body]

On Sunday 06 October 2002 17:42, Maks Orlovich wrote:
> Till Krech wrote:
> > On Sunday 06 October 2002 16:04, Shu-yu Guo wrote:
> >> Hello,
> >>
> >> Upon trying 3.1-beta2, konqueror crashes with a segfault upon exit. So,
> >> I decided to switch back to branch, unfortunately, this happens in
> >> branch as well. The backtrace in branch is different, and I have no idea
> >> what is causing this, though I'm leaning towards qt since that has
> >> changed since last time I used branch.
> >>
> >> FreeBSD 4.7-PRERELEASE,
> >> gcc version 2.95.4 20020320 [FreeBSD]
> >> KDE_3_0_BRANCH built from CVS
> >> qt-copy 3.1.0-b2
> >
> > Same here.
> > The following code, enhanced with debug output to track down the problem,
> > is in kdebase/konqueror/konq_main.cc . Look at the comment!
> > -------------------------------------------------------------
> >   app.exec();
> >
> >  //// Temporary code, waiting for Qt to do this properly
> >
> >   // Delete all toplevel widgets that have WDestructiveClose, so that we
> >   don't have // any parts loaded when KLibLoader::cleanUp is called.
> >   QWidgetList *list = QApplication::topLevelWidgets();
> >   QWidgetListIt it(*list);
> >   QWidget * w;
> >
> >   qDebug( "count: %i", list->count() );
> >   int i=0;
> >   while( (w=it.current()) != 0 ) {
> >      ++it;
> >      ++i;
> >      qDebug( "#%3i: Class: %s, Name: %s", i, w->className(), w->name() );
> >      if ( w->testWFlags( Qt::WDestructiveClose ) )
> >           delete w;
> >   }··
> >
> >   KonqMainWindow::s_crashlog_file->remove();
>
> Adding:
>
> @@ -137,6 +139,7 @@ int main( int argc, char **argv )
>    QWidgetListIt it(*list);
>    QWidget * w;
>    while( (w=it.current()) != 0 ) {
> +     qDebug("Testing:%s, flags=%d", w->className(),  w->testWFlags(
> Qt::WDestructiveClose ) );
>       ++it;
>       if ( w->testWFlags( Qt::WDestructiveClose ) )
>            delete w;
>
> In the debug output I get:
> ....
> Testing:QWidget, flags=0
> Testing:KonqMainWindow, flags=0
> Testing:KPopupMenu, flags=0
> ......
Funny. So this whole loop simply does nothing since none of the widgets has 
WDestructiveClose set. Maybe it id something in previous Qt versions.
>
> But in KonqMainWindow ctor, we have:
> KonqMainWindow::KonqMainWindow( const KURL &initialURL, bool
> openInitialURL, const char *name )
>
>  : KParts::MainWindow( name, WDestructiveClose | WStyle_ContextHelp )
>
> So it probably somehow gets cleared or lost..
I searched for it but could not find out where it gets lost, just found two 
places where it was set again. I think it must be somewhere in Qt.

I've done some more investigation.
If you take a look at kdelibs/kdecore/kapplication.cpp, you will find this in
KApplication::~KApplication() :

  // First call the static deleters and then call KLibLoader::cleanup()
  // The static deleters may delete libraries for which they need KLibLoader.
  // KLibLoader will take care of the remaining ones.
  KGlobal::deleteStaticDeleters();
  KLibLoader::cleanUp();

deleteStaticDeleters does  the following:      
    delete KGlobal::_staticDeleters;
    KGlobal::_staticDeleters = 0;

later on in KLibLoader::cleanUp() the function registerStaticDeleter(obj) is 
called indirectly: 

   if (!_staticDeleters)
      kglobal_init();
   if (_staticDeleters->find(obj) == -1)
      _staticDeleters->append(obj);

Now, one could asume that kglobal_init() takes care of a non null value of 
_staticDeleters. In fact is does not since it returns immediately if the 
static variable addedFreeAll has been once set to true:

static bool addedFreeAll = false;

static void kglobal_init()
{
    if (addedFreeAll)
        return;

    addedFreeAll = true;
    KGlobal::_staticDeleters = new KStaticDeleterList;

    qAddPostRoutine( kglobal_freeAll );
}

so, registerStaticDeleter crashes in 
 _staticDeleters->find(obj)
with a this=0.

If, without knowing it better, I swap the two lines in 
KApplication::~KApplication

  KLibLoader::cleanUp();
  KGlobal::deleteStaticDeleters();

it does not crash anymore in file manager mode but there is still a crash when 
closing konqueror from "normal" html mode.

I also tried to "refine" a bit the logic of kglobal_init albut so without 
success.

regards, till


-- 
Till Krech from Berlin, Germany is happy with
SuSE Linux 8.0 (i386) 2.4.18-64GB-SMP * KDE: 3.0.8 (KDE 3.1 beta2)
Qt: 3.1.0-b2 * gcc version 3.2


>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic