Patch: Crash: blocking JS alert and deleting a window

Koos Vriezen koos.vriezen at xs4all.nl
Sat Oct 26 16:21:17 BST 2002


On Thu, 24 Oct 2002, David Faure wrote:

> Here's a patch for this solution. Much easier to understand and follow in a debugger,
> much more predictable, but it reimplements some logic that's already somewhere else
> in KDialogBase.

Thanks for you improvements on this.

The initial test case still crashes though, when closing the second
window with the X button:
<html><head><script>
  var win=open("", "xxx");
  var doc=win.document;
  doc.open();
  doc.write("<html><script>'alert(somevar)'</script><body></body></html>");
  doc.close();
</script></head>
<body></body></html>

There were two cases were blocking JS crashes a closing khtml part, the
liveconnect calls (with that dirty usleep/processEvents sync) and dialog
boxes (that do a enter_loop).

Liveconnect calls are now sync'ed by using 'select' on the stdout/stdin
fd's. When debuging the dialogs, I realized that LC calls could be sync'ed
as well with enter_loop (using QEventLoop because
QApplication::enter_loop() is deprecated). This add a possible crash when
the part exits inside such a loop, but since it is already the case with
dialogs, it's not a new headache. Just exits these loops as we do on
dialogs now (well we try, but fail here).

Solving this first case, other than blaming Qt for sending a CloseEvent to
a window that has a modal dialog, means
- the part has to be informed that it will be destroyed and the part
  should be deleted with deleteLater (way isn't deleteLater virtual?), or
- separates all functions from KHTMLPart in a new object where a JS call
  may pass before blocking on such a enter_loop call and deleteLater it.
- other ways?

Well forget the second option, but the first one could be implemented with
only a minor change in konq_view.cc; delete -> deleteLater

--- konq_view.cc        2002/10/17 16:24:50     1.316
+++ konq_view.cc        2002/10/26 15:08:23
@@ -115,7 +115,7 @@ KonqView::~KonqView()
     if ( isPassiveMode() )
       disconnect( m_pPart, SIGNAL( destroyed() ),
m_pMainWindow->viewManager(), SLOT( slotObjectDestroyed() ) );

-    delete m_pPart;
+    m_pPart->deleteLater();
   }

   setRun( 0L );
@@ -216,7 +216,7 @@ void KonqView::switchView( KonqViewFacto
   {
     m_pPart->setName( oldPart->name() );
     emit sigPartChanged( this, oldPart, m_pPart );
-    delete oldPart;
+     oldPart->deleteLater();
   }

Looks like we can't override deleteLater but, but since it post a
DeferredDelete event, it can be filtered, call
KHTMLView::closeChildDialogs and call deleteLater again (not doing the
same the next time of course).

bool KHTMLPart::event ( QEvent * e ) {
  if (e->type () == QEvent::DeferredDelete && !d->m_delayDelete) {
    if ( d->m_view )
      d->m_view->closeChildDialogs();
    d->m_delayDelete = true;
    deleteLater();
    return true;
  }
  return false;
}

should do it (also adding bool m_delayDelete). Unfortunately the above
test case still crashes because
#0  0x4152c978 in KHTMLView::~KHTMLView() ()
#1  0x40b19b40 in QWidget::~QWidget() ()
#2  0x4009d391 in KonqFrame::~KonqFrame() ()
#3  0x40b19b40 in QWidget::~QWidget() ()
#4  0x40bbc13d in QMainWindow::~QMainWindow() ()
#5  0x4059b077 in KMainWindow::~KMainWindow() ()
#6  0x4017ba2e in KParts::MainWindow::~MainWindow() ()
#7  0x4005bfe1 in KonqMainWindow::~KonqMainWindow() ()
#8  0x40aed150 in QObject::event(QEvent*) (

still happens in the dialogs message loop (and the tokenizer is still
running). Ok KPart::slotWidgetDestroyed() also deletes the part,
deleteLater it too, still a crash (part not being deleted this time).
What more is gone.... Any ideas?

Koos





More information about the kfm-devel mailing list