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